package com.jieli.stream.dv.running2.ui.activity;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.projection.MediaProjectionManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.LinearInterpolator;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.MediaController;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TableLayout;
import android.widget.TextView;

import com.jieli.lib.dv.control.DeviceClient;
import com.jieli.lib.dv.control.connect.response.SendResponse;
import com.jieli.lib.dv.control.intercom.IntercomManager;
import com.jieli.lib.dv.control.json.bean.NotifyInfo;
import com.jieli.lib.dv.control.model.PictureInfo;
import com.jieli.lib.dv.control.projection.OnSendStateListener;
import com.jieli.lib.dv.control.utils.Dlog;
import com.jieli.stream.dv.running2.interfaces.OnClickStateListener;
import com.jieli.stream.dv.running2.task.DebugHelper;
import com.jieli.stream.dv.running2.task.IDebugListener;
import com.jieli.lib.dv.control.player.OnFrameListener;
import com.jieli.lib.dv.control.player.OnRealTimeListener;
import com.jieli.lib.dv.control.player.RealtimeStream;
import com.jieli.lib.dv.control.player.Stream;
import com.jieli.lib.dv.control.player.VideoThumbnail;
import com.jieli.lib.dv.control.receiver.listener.OnNotifyListener;
import com.jieli.lib.dv.control.utils.Code;
import com.jieli.lib.dv.control.utils.Topic;
import com.jieli.lib.dv.control.utils.TopicKey;
import com.jieli.lib.dv.control.utils.TopicParam;
import com.jieli.media.codec.FrameCodec;
import com.jieli.media.codec.bean.MediaMeta;
import com.jieli.stream.dv.running2.R;
import com.jieli.stream.dv.running2.audio.AudioRecordManager;
import com.jieli.stream.dv.running2.bean.DeviceDesc;
import com.jieli.stream.dv.running2.bean.DeviceSettingInfo;
import com.jieli.stream.dv.running2.bean.FileInfo;
import com.jieli.stream.dv.running2.bean.RequestFileInfo;
import com.jieli.stream.dv.running2.bean.ThumbnailInfo;
import com.jieli.stream.dv.running2.data.OnRecordStateListener;
import com.jieli.stream.dv.running2.data.OnVideoCaptureListener;
import com.jieli.stream.dv.running2.data.VideoCapture;
import com.jieli.stream.dv.running2.data.VideoRecord;
import com.jieli.stream.dv.running2.ui.MainApplication;
import com.jieli.stream.dv.running2.ui.adapter.CoverAdapter;
import com.jieli.stream.dv.running2.ui.base.BaseActivity;
import com.jieli.stream.dv.running2.ui.dialog.DownloadDialog;
import com.jieli.stream.dv.running2.ui.dialog.NotifyDialog;
import com.jieli.stream.dv.running2.ui.dialog.WaitingDialog;
import com.jieli.stream.dv.running2.ui.widget.PlaybackSeekbar;
import com.jieli.stream.dv.running2.ui.widget.PopupMenu;
import com.jieli.stream.dv.running2.ui.widget.coverflow.CoverFlowLayoutManger;
import com.jieli.stream.dv.running2.ui.widget.coverflow.RecyclerCoverFlow;
import com.jieli.stream.dv.running2.ui.widget.media.IMediaController;
import com.jieli.stream.dv.running2.ui.widget.media.IRenderView;
import com.jieli.stream.dv.running2.ui.widget.media.IjkVideoView;
import com.jieli.stream.dv.running2.ui.widget.media.InfoHudViewHolder;
import com.jieli.stream.dv.running2.util.AppUtils;
import com.jieli.stream.dv.running2.util.ClientManager;
import com.jieli.stream.dv.running2.util.Dbug;
import com.jieli.stream.dv.running2.util.HttpManager;
import com.jieli.stream.dv.running2.util.IConstant;
import com.jieli.stream.dv.running2.util.PreferencesHelper;
import com.jieli.stream.dv.running2.util.ThumbnailManager;
import com.jieli.stream.dv.running2.util.ThumbnailRequestQueue;
import com.jieli.stream.dv.running2.util.TimeFormate;
import com.jieli.stream.dv.running2.util.ToastUtil;
import com.jieli.stream.dv.running2.util.json.JSonManager;
import com.jieli.stream.dv.running2.util.json.listener.OnCompletedListener;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.ResponseBody;
import tv.danmaku.ijk.media.player.IMediaPlayer;
import tv.danmaku.ijk.media.player.IjkMediaPlayer;

import static android.support.v7.widget.RecyclerView.SCROLL_STATE_DRAGGING;
import static com.jieli.lib.dv.control.utils.Constants.SEND_SUCCESS;

public class PlaybackActivity extends BaseActivity implements View.OnClickListener, AudioRecordManager.RecorderListener,
        OnSendStateListener {
    private String tag = getClass().getSimpleName();
    private RelativeLayout topBar;
    private ImageView mReturn;
    private TextView tvTop;
    private ImageView mCancel;
    private RelativeLayout layoutPreview;
    private LinearLayout leftControlBar;
    private ImageView mSwitchCameraBtn;
    private ImageView mAdjustResolutionBtn;
    private ImageView mProjectionBtn;
    private ImageView mBrowseGallery;
    private LinearLayout centerControlBar;
    private ImageView mPhotoBtn;
    private ImageView mVoiceBtn;
    private ImageView mVideoBtn;
    private ImageView mRecordFlag;
    private ImageView mProjectionFlag;
    private RelativeLayout layoutBrowse;
    private TextView mPositionTime;
    private TextView tvAutoPlayTip;
    private RecyclerCoverFlow mCoverFlowCarousel;
    private IjkVideoView mStreamView;
    private ProgressBar mLoadingView;
    private PlaybackSeekbar playbackSeekbar;
    private NotifyDialog mLocalRecordingDialog;
    private ImageView mLockFileBtn;
    private ImageView mDeleteFileBtn;
    private ImageView mCycSaveVideo;
    private ImageButton mRTSPlayButton;//Live only
    private TableLayout mHudView;

    private NotifyDialog mLoadingDialog;
    private NotifyDialog mErrorDialog;
    private PopupMenu popupMenu;
    private NotifyDialog operationFileDialog;
    private WaitingDialog mWaitingDialog;
    private WaitingDialog mAdjustingDialog;

    private PowerManager.WakeLock wakeLock;
    private RealtimeStream mRealtimeStream;
    private VideoThumbnail mVideoThumbnail;
    private FrameCodec mFrameCodec = null;
    private CoverAdapter mAdapter;
    private AudioRecordManager mAudioManager;
    private IntercomManager intercomManager;
    private VideoRecord mRecordVideo;
    private VideoCapture mVideoCapture;
    private DebugHelper mDebugHelper;

    private List<FileInfo> mFileInfoList;
    private NotifyDialog mDeleteFileDialog;
    private NotifyDialog mStopLocalRecordingDialog;
    private List<String> mReady2DeleteList = new ArrayList<>();
    private int mCameraType = DeviceClient.CAMERA_FRONT_VIEW;
    private int recordStatus = -1;
    private int playbackMode;
    private boolean isIJKPlayerOpen;
    private boolean isProjection;
    private boolean isRtVoiceOpen;
    private boolean isRecordPrepared = false;//For no-card of device mode only
    private boolean isCapturePrepared = false;//For no-card of device mode only
    private boolean isAdjustResolution;
    private boolean isRtspEnable;
    private boolean isSwitchCamera;
    private boolean isChecked = false;//For select all file to delete
    private boolean isDeleteAll = false;
    private boolean isOnPause  = false;
    private boolean isStartDebug;
    private int threshold;
    private int fps;
    private final static int OP_DELETE_FILE = 0;
    private final static int OP_LOCK_FILE = 1;

    private ThumbnailRequestQueue thumbnailRequestQueue = new ThumbnailRequestQueue();

    private static final long DELAY_TIME = 100L;
    private static final int MODE_PREVIEW = 0x0101;
    private static final int MODE_BROWSE = 0x0102;

    private static final int MSG_TAKE_VIDEO = 0x0a00;
    private static final int MSG_TAKE_PHOTO = 0x0a01;
    private static final int MSG_PROJECTION_CONTROL = 0x0a02;
    private static final int MSG_RT_VOICE_CONTROL = 0x0a03;
    private static final int MSG_CYC_SAVE_VIDEO = 0x0a04;
    private static final int MSG_FPS_COUNT = 0x0a05;
    private Handler mHandler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message message) {
            if (message != null) {
                boolean open = false;
                switch (message.what) {
                    case MSG_TAKE_VIDEO:
                        if(MainApplication.getApplication().isSdcardExist()) {
                            switch (recordStatus) {
                                case STATUS_PREPARE:
                                    ToastUtil.showToastShort(getString(R.string.open_video_tip));
                                    break;
                                case STATUS_NOT_RECORD:
                                    open = true;
                                case STATUS_RECORDING:
                                    ClientManager.getClient().tryToRecordVideo(open, new SendResponse() {
                                        @Override
                                        public void onResponse(Integer code) {
                                            if (code != SEND_SUCCESS) {
                                                Dbug.e(tag, "Send failed");
                                            }
                                        }
                                    });
                                    break;
                            }
                        }else{
                            if(isPlaying()){
                                if (isRtspEnable) {
                                    ToastUtil.showToastLong(getString(R.string.not_supported_in_rtsp_mode));
                                    break;
                                }
                                if(!AppUtils.isFastDoubleClick(2000)){
                                    if (isRecordPrepared)
                                        stopLocalRecording();
                                    else
                                        showLocalRecordDialog();
                                }else{
                                    ToastUtil.showToastShort(getString(R.string.dialod_wait));
                                }
                            } else {
                                ToastUtil.showToastShort(getString(R.string.open_rts_tip));
                            }
                        }
                        break;
                    case MSG_TAKE_PHOTO:
                        if(MainApplication.getApplication().isSdcardExist()) {
                            ClientManager.getClient().tryToTakePhoto(new SendResponse() {
                                @Override
                                public void onResponse(Integer code) {
                                    if (code != SEND_SUCCESS) {
                                        Dbug.e(tag, "Send failed");
                                    }
                                }
                            });
                        }else{
                            if(isPlaying()){
                                if (isRtspEnable) {
                                    ToastUtil.showToastLong(getString(R.string.not_supported_in_rtsp_mode));
                                    break;
                                }
                                if (mVideoCapture == null) {
                                    mVideoCapture = new VideoCapture();
                                    mVideoCapture.setOnCaptureListener(new OnVideoCaptureListener() {
                                        @Override
                                        public void onCompleted() {
                                            isCapturePrepared = false;
                                        }

                                        @Override
                                        public void onFailed() {
                                            isCapturePrepared = false;
                                            ToastUtil.showToastShort(getString(R.string.failure_photo));
                                        }
                                    });
                                }
                                shootSound();
                                isCapturePrepared = true;
                            }else{
                                if(!isAdjustResolution){
                                    ToastUtil.showToastShort(getString(R.string.open_rts_tip));
                                }
                            }
                        }
                        break;
                    case MSG_PROJECTION_CONTROL:
                        if (!isProjection) {
                            requestCapturePermission();
                        } else {
                            ClientManager.getClient().tryToStreamingPush(false, 0, 0, 0, new SendResponse() {
                                @Override
                                public void onResponse(Integer code) {

                                }
                            });
                            isProjection = false;
                            handlerProjectionUI();
                            if (!isPlaying()) {
                                openRTS();
                            }
                        }
                        break;
                    case MSG_RT_VOICE_CONTROL:
                        if (isRtspEnable) {
                            ToastUtil.showToastLong(getString(R.string.not_supported_in_rtsp_mode));
                            break;
                        }
                        ClientManager.getClient().tryToRTIntercom(!isRtVoiceOpen, new SendResponse() {
                            @Override
                            public void onResponse(Integer code) {

                            }
                        });
                        break;
                    case MSG_CYC_SAVE_VIDEO:
                        //开始循环保存录像
                        if(recordStatus == STATUS_RECORDING){
                            if (mLoadingDialog != null && !mLoadingDialog.isShowing()) {
                                mLoadingDialog.show(getSupportFragmentManager(), "LoadingDialog");
                            }
                            ClientManager.getClient().tryToSaveCycVideo(new SendResponse() {
                                @Override
                                public void onResponse(Integer code) {

                                }
                            });
                        }else{
                            ToastUtil.showToastShort(getString(R.string.no_video_tip));
                        }
                        break;
                    case MSG_FPS_COUNT:
                        updateDebugFps(fps);
                        fps = 0;
                        mHandler.removeMessages(MSG_FPS_COUNT);
                        mHandler.sendEmptyMessageDelayed(MSG_FPS_COUNT, 1000);
                        break;
                }
            }
            return false;
        }
    });

    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (context != null && !TextUtils.isEmpty(action)) {
                switch (action) {
                    case ACTION_FORMAT_TF_CARD:
                        mHandler.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                dismissWaitingDialog();
                            }
                        }, 1000);
                        handleTFOffline();
                        break;
                }
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Dbug.i(tag, "==================CREATE===============");
        WindowManager.LayoutParams windowParams = getWindow().getAttributes();
        requestWindowFeature(Window.FEATURE_NO_TITLE); //设置无标题
        windowParams.flags = WindowManager.LayoutParams.FLAG_FULLSCREEN;
        getWindow().setAttributes(windowParams);
        setContentView(R.layout.activity_playback);
        isRtspEnable = PreferencesHelper.getSharedPreferences(mApplication).getBoolean(KEY_RTSP, false);
        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        if (pm != null) wakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, tag);
        wakeLock.setReferenceCounted(false);
        threshold = AppUtils.dp2px(this, 20);
        initUI();
        Intent intent = getIntent();
        FileInfo fileInfo = null;
        if (intent != null) {
            fileInfo = (FileInfo) intent.getSerializableExtra(KEY_FILE_INFO);
        }
        if (fileInfo != null) {
            playbackMode = MODE_BROWSE;
            playbackSeekbar.setModeNotCallback(PlaybackSeekbar.BROWSE_COVER_MODE);
        } else {
            playbackMode = MODE_PREVIEW;
            playbackSeekbar.setModeNotCallback(PlaybackSeekbar.REAL_TIME_STREAM_MODE);
        }
        if (!mApplication.isSdcardExist()) {
            playbackSeekbar.setVisibility(View.INVISIBLE);
        }
        ClientManager.getClient().registerNotifyListener(onNotifyListener);
        requestFileMsgText();
        mAdapter.setOnItemClickListener(new CoverAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(View view, final int position) {
                recordStatus = MainApplication.getApplication().getDeviceSettingInfo().getRecordState();
                if (recordStatus == STATUS_RECORDING) {
                    mHandler.removeCallbacks(autoPlayRunnable);
                    tryToStopRecording(position);
                } else {
                    FileInfo fileInfo = mAdapter.getItem(position);
                    ToastUtil.showToastShort(fileInfo.getName());
                    showPlaybackDialog(fileInfo.getPath(), fileInfo.getStartTime().getTimeInMillis());
                }
            }

            @Override
            public void onItemLongClick(View view, int position) {
                mHandler.removeCallbacks(autoPlayRunnable);
                FileInfo fileInfo = mAdapter.getItem(position);
                if(fileInfo != null){
                    showProgressDialog(fileInfo);
                }
            }
        });
        //registerBroadcast();
        mCoverFlowCarousel.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                //Dbug.i(tag, "new state=" + newState);
                if (newState == SCROLL_STATE_DRAGGING && mAdapter.getItemCount() > 0) {
                    mHandler.removeCallbacks(autoPlayRunnable);
                    playbackSeekbar.setMode(PlaybackSeekbar.BROWSE_CONTENT_MODE);
                    mCancel.setVisibility(View.VISIBLE);
                }
            }

        });
        mCoverFlowCarousel.setOnItemSelectedListener(new CoverFlowLayoutManger.OnSelected() {
            @Override
            public void onItemSelected(int position) {
                if (position < 0 || position >= mAdapter.getItemCount() || position >= mFileInfoList.size()) {
                    return;
                }
                Dbug.i(tag, "selected position=" + position);
                ThumbnailInfo f = mAdapter.getItem(position);
                if (f == null) {
                    Dbug.e(tag, "The position of file info is null");
                    return;
                }
                handleSelectedFile(position);
            }
        });
    }

    private void handleSelectedFile(int position) {
        updateCoverFlowCarousel();
        if (position == mAdapter.getItemCount() - 1 && mAdapter.getItemCount() < mFileInfoList.size() && thumbnailRequestQueue.isEmpty()) {
            Dbug.i(tag, "position=" + position + ", getItemCount=" + mAdapter.getItemCount());
            int pos = mAdapter.getItemCount() + IConstant.PAGE_SIZE < mFileInfoList.size() ? (mAdapter.getItemCount() + IConstant.PAGE_SIZE) : mFileInfoList.size();
            requestVideoThumbnail(mFileInfoList.subList(position + 1, pos));
        }
        FileInfo selectFileInfo = mAdapter.getItem(mCoverFlowCarousel.getSelectedPos());
        if(selectFileInfo != null){
            Dbug.i(tag, "mSelectedFileInfo--> name=" + selectFileInfo.getName() + "  time=" + selectFileInfo.getCreateTime());
            mPositionTime.setText(yyyyMMddHHmmss.format(selectFileInfo.getStartTime().getTimeInMillis()));
            //置空bitmap引用，让系统可以回收bitmap
            mAdapter.clearContentThumbnail();
            playbackSeekbar.setFileInfo(selectFileInfo);
            handlerFileLockState(selectFileInfo);
            //自动播放
            handleAutoPlay();
        }
    }

    private void initUI() {
        //top bar
        topBar = (RelativeLayout) findViewById(R.id.playback_top_bar);
        mReturn = (ImageView) findViewById(R.id.return_back);
        tvTop = (TextView) findViewById(R.id.playback_top_tv);
        mCancel = (ImageView) findViewById(R.id.cancle_time_select_ibtn);

        //rt stream
        mStreamView = (IjkVideoView) findViewById(R.id.playback_rt_stream_view);
        mStreamView.setAspectRatio(IRenderView.AR_MATCH_PARENT);
        mStreamView.setOnErrorListener(mOnErrorListener);
        mStreamView.setMediaController(iMediaController);
        mStreamView.setOnTouchListener(mOnTouchListener);
        mStreamView.setOnCompletionListener(onCompletionListener);
        mStreamView.setOnPreparedListener(onPreparedListener);
        mLoadingView = (ProgressBar) findViewById(R.id.playback_rt_stream_loading);

        //preview mode
        layoutPreview = (RelativeLayout) findViewById(R.id.playback_preview_mode);
        leftControlBar = (LinearLayout) findViewById(R.id.preview_mode_left_bar);
        mAdjustResolutionBtn = (ImageView) findViewById(R.id.left_bar_adjust_resolution_btn);
        mProjectionBtn = (ImageView) findViewById(R.id.left_bar_projection_btn);
        mBrowseGallery = (ImageView) findViewById(R.id.left_bar_browse_photo_btn);
        centerControlBar = (LinearLayout) findViewById(R.id.preview_mode_center_bar);
        mPhotoBtn = (ImageView) findViewById(R.id.center_bar_photo_btn);
        mVoiceBtn = (ImageView) findViewById(R.id.center_bar_voice_btn);
        mVideoBtn = (ImageView) findViewById(R.id.center_bar_video_btn);
        mRecordFlag = (ImageView) findViewById(R.id.status_bar_record_flag);
        mProjectionFlag = (ImageView) findViewById(R.id.status_bar_projection_flag);
        mSwitchCameraBtn = (ImageView) findViewById(R.id.left_bar_switch_camera_btn);
        mCycSaveVideo = (ImageView) findViewById(R.id.left_bar_cyc_save_video);
        mRTSPlayButton = (ImageButton) findViewById(R.id.rts_play);

        //browse mode
        layoutBrowse = (RelativeLayout) findViewById(R.id.playback_browse_mode);
        mPositionTime = (TextView) findViewById(R.id.position_of_time);
        tvAutoPlayTip = (TextView) findViewById(R.id.auto_play_tip);
        mCoverFlowCarousel = (RecyclerCoverFlow) findViewById(R.id.carousel);

        //bottom time line
        playbackSeekbar = (PlaybackSeekbar) findViewById(R.id.time_seekbar);

        //browse control
        mLockFileBtn = (ImageView) findViewById(R.id.left_bar_lock_btn);
        mDeleteFileBtn = (ImageView) findViewById(R.id.left_bar_delete_file_btn);

        mHudView = (TableLayout) findViewById(R.id.hud_view);

        //反转视图
        //mCoverFlowCarousel.setRotationY(180);
        tvAutoPlayTip.setVisibility(View.INVISIBLE);
        mReturn.setOnClickListener(this);
        mCancel.setOnClickListener(this);
        mAdjustResolutionBtn.setOnClickListener(this);
        mProjectionBtn.setOnClickListener(this);
        mBrowseGallery.setOnClickListener(this);
        mPhotoBtn.setOnClickListener(this);
        mVoiceBtn.setOnClickListener(this);
        mVideoBtn.setOnClickListener(this);
        playbackSeekbar.setOnStatechangeListener(onStatechangeListener);
        mSwitchCameraBtn.setOnClickListener(this);
        mLockFileBtn.setOnClickListener(this);
        mDeleteFileBtn.setOnClickListener(this);
        mCycSaveVideo.setOnClickListener(this);
        mRTSPlayButton.setOnClickListener(this);

        DeviceDesc deviceDesc = MainApplication.getApplication().getDeviceDesc();
        if(deviceDesc != null){
            if(!deviceDesc.isSupport_projection()){
                mProjectionBtn.setVisibility(View.GONE);
            }else{
                mProjectionBtn.setVisibility(View.VISIBLE);
            }
        }

        mAdapter = new CoverAdapter(this);
        mCoverFlowCarousel.setAdapter(mAdapter);

        mLoadingDialog = NotifyDialog.newInstance(R.string.loading, true, -1, (R.string.dialog_cancel), new NotifyDialog.OnConfirmClickListener() {
            @Override
            public void onClick() {
                mLoadingDialog.dismiss();
                onBackPressed();
            }
        });
        mLoadingDialog.setOnDismissDialogListener(new NotifyDialog.OnDismissDialogListener() {
            @Override
            public void onDismiss() {
                Dbug.w(tag, "mLoadingDialog is dismiss.");
                Intent intent = getIntent();
                FileInfo fileInfo = null;
                if (intent != null) {
                    fileInfo = (FileInfo) intent.getSerializableExtra(KEY_FILE_INFO);
                }
                if (fileInfo == null) {
                    Dbug.e(tag, "fileInfo is null.");
                    return;
                }
                int index = findFileInfoIndex(fileInfo);
                if (playbackMode == MODE_BROWSE && mFileInfoList != null && index > -1 && index < mAdapter.getItemCount()) {
                    fileInfo = mAdapter.getItem(index);
                    if (fileInfo != null) {
                        mCoverFlowCarousel.setSelectPosition(index);
                        playbackSeekbar.setBrowsePostion(index);
                        playbackSeekbar.setFileInfo(fileInfo);
                        playbackSeekbar.setMode(PlaybackSeekbar.BROWSE_CONTENT_MODE);
                        if (index==0){
                            handleSelectedFile(index);
                        }
                    }
                }
            }
        });

    }

    @Override
    protected void onStart() {
        super.onStart();
        registerBroadcast();
    }

    private void registerBroadcast() {
        IntentFilter filter = new IntentFilter();
        filter.addAction(ACTION_FORMAT_TF_CARD);
        MainApplication.getApplication().registerReceiver(mReceiver, filter);
    }

    private void handleAutoPlay() {
        if (!isOnPause && mHandler != null && mAdapter.getItemCount() > 0) {
            Dbug.i(tag, "handleAutoPlay");
            tvAutoPlayTip.setVisibility(View.VISIBLE);
            mHandler.removeCallbacks(autoPlayRunnable);
            mHandler.postDelayed(autoPlayRunnable, AUTO_TIME);
        }
    }

    private Runnable autoPlayRunnable = new Runnable() {
        @Override
        public void run() {
            if (playbackMode != MODE_BROWSE) {
                return;
            }
            if (mLoadingDialog != null && mLoadingDialog.isShowing()) {
                handleAutoPlay();
                return;
            }
            int selectPos = mCoverFlowCarousel.getSelectedPos();
            FileInfo selectedFileInfo = mAdapter.getItem(selectPos);
            if (selectedFileInfo != null) {
                ToastUtil.showToastShort(selectedFileInfo.getName());
                showPlaybackDialog(selectedFileInfo.getPath(), selectedFileInfo.getStartTime().getTimeInMillis());
            } else if (mAdapter.getItemCount() > 0) {
                ToastUtil.showToastShort(mAdapter.getItem(0).getName());
                showPlaybackDialog(mAdapter.getItem(0).getPath(), mAdapter.getItem(0).getStartTime().getTimeInMillis());
            }
        }
    };


    private PlaybackSeekbar.OnStatechangeListener onStatechangeListener = new PlaybackSeekbar.OnStatechangeListener() {
        @Override
        public void onBrowseCoverChange(int position) {
            // Dbug.i(tag, "onBrowseCoverChange pos=" + position);
            if (mAdapter.getItemCount() < 1) {
                mHandler.removeCallbacks(autoPlayRunnable);
                return;
            }
            if (Math.abs(position - mCoverFlowCarousel.getSelectedPos()) > 3) {
                mCoverFlowCarousel.setSelectPosition(position);
            } else if (position < mAdapter.getItemCount()) {
                mCoverFlowCarousel.setSelectPositionByScroll(position);
            }
        }

        @Override
        public void onBrowseContentChange(long time, int offset) {
            mPositionTime.setText(yyyyMMddHHmmss.format(time));
            FileInfo selectedFileInfo = mAdapter.getItem(mCoverFlowCarousel.getSelectedPos());
            if (selectedFileInfo != null) {
                if (mVideoThumbnail == null || !mVideoThumbnail.isReceiving()) {
                    requestVideoContentThumbnail(selectedFileInfo, offset, 1);
                }
                // contentPos = mCoverFlowCarousel.getSelectedPos();
            }
            handleAutoPlay();
        }

        @Override
        public void onModeChange(int mode) {
            Dbug.i(tag, "onModeChange="+PlaybackSeekbar.modeToString(mode));
            switch (mode) {
                //browse mode
                case PlaybackSeekbar.BROWSE_CONTENT_MODE:
                    mCancel.setVisibility(View.VISIBLE);
                    break;
                case PlaybackSeekbar.BROWSE_COVER_MODE:
                    if (mApplication.isSdcardExist()) {
                        enterVideosBrowserMode();
                    } else {
                        ToastUtil.showToastLong(getString(R.string.sdcard_offline));
                    }
                    break;
                //preview mode
                case PlaybackSeekbar.REAL_TIME_STREAM_MODE:
                    Dbug.i(tag, "real time mode");
                    mHandler.removeCallbacks(autoPlayRunnable);
                    updateModeUI(MODE_PREVIEW);
                    break;
            }
        }
    };

    private void enterVideosBrowserMode() {
        mCancel.setVisibility(View.INVISIBLE);
        if (playbackMode == MODE_PREVIEW) {
            //Dbug.i(tag, "realtime mode to cover browse mode");
            //contentPos = mCoverFlowCarousel.getSelectedPos();
            if (mAdapter.getItemCount() > 0) {
                FileInfo selectedFileInfo = mAdapter.getItem(mCoverFlowCarousel.getSelectedPos());
                playbackSeekbar.setFileInfo(selectedFileInfo);
                playbackSeekbar.setFileInfoCount(mAdapter.getItemCount());
                mPositionTime.setText(yyyyMMddHHmmss.format(selectedFileInfo.getStartTime().getTimeInMillis()));
                handleAutoPlay();
            } else {
                mHandler.removeCallbacks(autoPlayRunnable);
            }
        }
        updateModeUI(MODE_BROWSE);
    }
    private final FrameCodec.OnFrameCodecListener mOnFrameCodecListener = new FrameCodec.OnFrameCodecListener() {
        @Override
        public void onCompleted(final byte[] bytes, final MediaMeta mediaMeta) {
            Dbug.i(tag, "mOnFrameCodecListener");
            if(mediaMeta == null) return;
            RequestFileInfo requestFileInfo = thumbnailRequestQueue.peek();
            if (requestFileInfo == null || (requestFileInfo.getFileInfo() != null &&
                    !mediaMeta.getPath().equals(requestFileInfo.getFileInfo().getPath()))) {
                Dbug.i(tag, " mediaMeta.getPath err=" + mediaMeta.getPath());
                //showToastShort(R.string.thumbnail_load_fail);
                stopThumbnailReceive();
                return;
            }
            thumbnailRequestQueue.poll();
            if (thumbnailRequestQueue.isEmpty()) {
                stopThumbnailReceive();
            }
            if (requestFileInfo.isContent()) {
                int selectedPos = mCoverFlowCarousel.getSelectedPos();
                if (selectedPos < mAdapter.getItemCount() && mAdapter.getItem(selectedPos).getPath().equals(mediaMeta.getPath())) {
                    BitmapFactory.Options options = new BitmapFactory.Options();
                    options.inSampleSize = 4;
                    options.inPreferredConfig = Bitmap.Config.RGB_565;
                    final Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
                    mAdapter.getItem(selectedPos).setBitmap(bitmap);
                    mAdapter.setContentThumbnailFlag(selectedPos);
                }
            } else {
                //isInsertFileInfo = false;
                String cameraDir = AppUtils.getMediaDirectory(requestFileInfo.getFileInfo().getCameraType());
                String path = AppUtils.splicingFilePath(mApplication.getAppName(), mApplication.getUUID(), cameraDir, IConstant.DIR_THUMB);
                File file = new File(path, AppUtils.getVideoThumbName(requestFileInfo.getFileInfo()));
                if (file.exists()) {
                    return;
                }
                AppUtils.bytesToFile(bytes, file.getPath());
            }
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    updateCoverFlowCarousel();
                    playbackSeekbar.setFileInfoCount(mAdapter.getItemCount());
                }
            });
        }

        @Override
        public void onError(String s) {
            Dbug.i(tag, "mOnFrameCodecListener err=" + s);
            thumbnailRequestQueue.poll();
            if (thumbnailRequestQueue.isEmpty()) {
                stopThumbnailReceive();
            }
        }
    };

    private void saveBitmapAndUpdateUI(byte[] bytes) {
        RequestFileInfo requestFileInfo = thumbnailRequestQueue.poll();
        if (requestFileInfo == null ) {
            Dbug.e(tag, "saveBitmapAndUpdateUI is null");
            stopThumbnailReceive();
            return;
        }
        if (thumbnailRequestQueue.isEmpty()) {
            stopThumbnailReceive();
        }
        if (requestFileInfo.isContent()) {
            int selectedPos = mCoverFlowCarousel.getSelectedPos();
            if (selectedPos < mAdapter.getItemCount() && mAdapter.getItem(selectedPos).getPath().equals(requestFileInfo.getFileInfo().getPath())) {
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inSampleSize = 4;
                options.inPreferredConfig = Bitmap.Config.RGB_565;
                final Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
                mAdapter.getItem(selectedPos).setBitmap(bitmap);
                mAdapter.setContentThumbnailFlag(selectedPos);
            }
        } else {
            //isInsertFileInfo = false;
            String cameraDir = AppUtils.getMediaDirectory(requestFileInfo.getFileInfo().getCameraType());
            String path = AppUtils.splicingFilePath(mApplication.getAppName(), mApplication.getUUID(), cameraDir, IConstant.DIR_THUMB);
            File file = new File(path, AppUtils.getVideoThumbName(requestFileInfo.getFileInfo()));
            if (file.exists()) {
                Dbug.w(tag, "File exist=" + file.getAbsolutePath());
                return;
            }
            AppUtils.bytesToFile(bytes, file.getPath());
        }
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                updateCoverFlowCarousel();
                playbackSeekbar.setFileInfoCount(mAdapter.getItemCount());
            }
        });
    }

    private void updateCoverFlowCarousel() {
        if (mCoverFlowCarousel.getScrollState() == RecyclerView.SCROLL_STATE_IDLE && (!mCoverFlowCarousel.isComputingLayout())) {
            if (!isDestroyed()) {
                mAdapter.notifyDataSetChanged();
            }
        }
    }

    private static final SimpleDateFormat yyyyMMddHHmmss = TimeFormate.yyyyMMddHHmmss;


    /**
     * 请求视频文件信息
     */
    private void requestFileMsgText() {
        if (mLoadingDialog != null && !mLoadingDialog.isShowing()) {
            mLoadingDialog.show(getSupportFragmentManager(), "LoadingDialog");
        }
        mCameraType = mApplication.getDeviceSettingInfo().getCameraType();
        Dbug.w(tag, "requestFileMsgText********************************mCameraType=" + mCameraType);
        ClientManager.getClient().tryToRequestMediaFiles(mCameraType, new SendResponse() {
            @Override
            public void onResponse(Integer code) {
                if (code != SEND_SUCCESS) {
                    Dbug.e(tag, "Send failed");
                    if (mLoadingDialog != null && mLoadingDialog.isShowing()) {
                        mLoadingDialog.dismiss();
                    }
                }
            }
        });
    }

    @Override
    public void onClick(View v) {
        if (v == mReturn) {
            if (isRecordPrepared) {
                showStopRecordingDialog(new OnClickStateListener() {
                    @Override
                    public void onCancel() {
                    }

                    @Override
                    public void onConfirm() {
                        stopLocalRecording();
                        mHandler.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                onBackPressed();
                            }
                        }, 100);
                    }
                });
            } else {
                onBackPressed();
            }
        } else if (v == mCancel) {
            mCoverFlowCarousel.stopScroll();
            playbackSeekbar.setMode(PlaybackSeekbar.BROWSE_COVER_MODE);
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    Dbug.i(tag, " click mCancle btn setBrowsePostion ");
                    playbackSeekbar.setBrowsePostion(mCoverFlowCarousel.getSelectedPos());
                }
            }, 50);
//            handleAutoPlay();
        } else if (v == mAdjustResolutionBtn) {
            if (mStreamView.isPlaying() || isPlaying()) {
                if (DEV_REC_DUAL.equals(mApplication.getDeviceDesc().getDevice_type()) && recordStatus == STATUS_RECORDING) {
                    ToastUtil.showToastShort(getString(R.string.stop_recording_first));
                } else {
                    showPopupMenu(v);
                }
            } else {
                ToastUtil.showToastShort(getString(R.string.open_rts_tip));
            }
        } else if (v == mProjectionBtn) {
            if (mHandler != null) {
                mHandler.removeMessages(MSG_PROJECTION_CONTROL);
                mHandler.sendEmptyMessageDelayed(MSG_PROJECTION_CONTROL, 500);
            }
        } else if (v == mBrowseGallery) {
            String txtContent = JSonManager.getInstance().getVideosDescription();
            if (isSdOnline() && !TextUtils.isEmpty(txtContent)) {
                Bundle bundle = new Bundle();
                bundle.putString(KEY_VIDEO_LIST, txtContent);
                Intent it = new Intent(this, GenericActivity.class);
                it.putExtra(KEY_FRAGMENT_TAG, DEV_PHOTO_FRAGMENT);
                it.putExtra(KEY_DATA, bundle);
                startActivityForResult(it, CODE_BROWSE_FILE);
            }
        } else if (v == mPhotoBtn) {
            if (mHandler != null) {
                mHandler.removeMessages(MSG_TAKE_PHOTO);
                mHandler.sendEmptyMessageDelayed(MSG_TAKE_PHOTO, DELAY_TIME);
            }
        } else if (v == mVoiceBtn) {
            if (mHandler != null) {
                mHandler.removeMessages(MSG_RT_VOICE_CONTROL);
                mHandler.sendEmptyMessageDelayed(MSG_RT_VOICE_CONTROL, DELAY_TIME);
            }
        } else if (v == mVideoBtn) {
            if (mHandler != null) {
                mHandler.removeMessages(MSG_TAKE_VIDEO);
                mHandler.sendEmptyMessageDelayed(MSG_TAKE_VIDEO, DELAY_TIME);
            }
        } else if (v == mSwitchCameraBtn) {
//            closeRTS();
            if (mHandler != null) {
                mHandler.removeCallbacks(switchCameraRunnable);
                mHandler.postDelayed(switchCameraRunnable, 300);
            }
        } else if (v == mLockFileBtn) {
            if (mHandler != null) {
                mHandler.removeCallbacks(autoPlayRunnable);
            }
            if (mAdapter != null) {
                FileInfo selectFileInfo = mAdapter.getItem(mCoverFlowCarousel.getSelectedPos());
                if (selectFileInfo != null) {
                    showOperationFileDialog(OP_LOCK_FILE, selectFileInfo);
                }
            }
        } else if (v == mDeleteFileBtn) {
            if (mHandler != null) {
                mHandler.removeCallbacks(autoPlayRunnable);
                mHandler.removeCallbacks(deleteFileRunnable);
                mHandler.postDelayed(deleteFileRunnable, DELAY_TIME);
            }
        } else if (v == mCycSaveVideo){
            if (isSdOnline() && mHandler != null) {
                mHandler.removeMessages(MSG_CYC_SAVE_VIDEO);
                mHandler.sendEmptyMessageDelayed(MSG_CYC_SAVE_VIDEO, DELAY_TIME);
            }
        } else if (v == mRTSPlayButton) {//Live only
            openRTS();
        }
    }

    private Runnable deleteFileRunnable = new Runnable() {
        @Override
        public void run() {
            if (mAdapter != null) {
                FileInfo selectFileInfo = mAdapter.getItem(mCoverFlowCarousel.getSelectedPos());
                if (selectFileInfo != null) {
                    int fileType = selectFileInfo.getType();
                    if (fileType == FILE_TYPE_SOS) {
                        showOperationFileDialog(OP_DELETE_FILE, selectFileInfo);
                    } else {
                        showDeleteFileDialog();
                    }
                } else {
                    ToastUtil.showToastShort(getString(R.string.null_data));
                }
            }
        }
    };

    private Runnable switchCameraRunnable = new Runnable() {
        @Override
        public void run() {
            if (!isSwitchCamera) {
                closeRTS();
                isSwitchCamera = true;
                int cameraType = mApplication.getDeviceSettingInfo().getCameraType();
                if (cameraType == DeviceClient.CAMERA_FRONT_VIEW) {
                    cameraType = DeviceClient.CAMERA_REAR_VIEW;
                } else {
                    cameraType = DeviceClient.CAMERA_FRONT_VIEW;
                }
                mApplication.getDeviceSettingInfo().setCameraType(cameraType);
                if (isRtspEnable) {
                    openRTS();
                    updateResolutionIcon();
                }
            } else Dbug.w(tag, "switchCameraRunnable: isSwitchCamera is true");
        }
    };

    @Override
    public void onBackPressed() {
        ClientManager.getClient().unregisterNotifyListener(onNotifyListener);
        setResult(Activity.RESULT_OK);
        finish();
    }

    private final OnNotifyListener onNotifyListener = new OnNotifyListener() {
        @Override
        public void onNotify(NotifyInfo data) {
            if(data == null) return;
            String topic = data.getTopic();
            if(TextUtils.isEmpty(topic) || topic.equals(Topic.KEEP_ALIVE)) return;
            if (data.getErrorType() != Code.ERROR_NONE) {
                Dbug.e(tag, "NotifyInfo:" + data + ", error:" + Code.getCodeDescription(data.getErrorType()));
                dismissWaitingDialog();
                if(recordStatus == STATUS_PREPARE){
                    recordStatus = STATUS_NOT_RECORD;
                }
                if(isAdjustResolution){
                    isAdjustResolution = false;
                    dismissAdjustingDialog();
                }
                switch (topic) {
                    case Topic.MULTI_VIDEO_COVER:
                    case Topic.VIDEO_CONTENT_THUMBNAILS:
                        if (mLoadingDialog != null && mLoadingDialog.isShowing()) {
                            mLoadingDialog.dismiss();
                        }
                        stopThumbnailReceive();
                        ToastUtil.showToastShort(getString(R.string.thumbnail_load_fail));
                        break;
                    case Topic.FRONT_MEDIA_FILE_LIST:
                    case Topic.REAR_MEDIA_FILE_LIST:
                        if (mLoadingDialog != null && mLoadingDialog.isShowing()) {
                            mLoadingDialog.dismiss();
                        }
                        //showErrorDialog(Code.getCodeDescription(data.getErrorType()));
                        break;
                    case Topic.CYC_SAVE_VIDEO:
                        Dbug.w(tag, "CYC SAVE VIDEO failed, reason : " + Code.getCodeDescription(data.getErrorType()));
                        ToastUtil.showToastShort(getString(R.string.cyc_save_video_failed));
                        break;
                }
                switch (data.getErrorType()){
                    case Code.ERROR_REAR_CAMERA_NOT_SUPPORT:
                        if(mSwitchCameraBtn != null && mSwitchCameraBtn.getVisibility() != View.GONE){
                            mSwitchCameraBtn.setVisibility(View.GONE);
                        }
                        MainApplication.getApplication().getDeviceSettingInfo().setCameraType(DeviceClient.CAMERA_FRONT_VIEW);
                        Dbug.w(tag, "The device does not support rear camera");
                        syncDeviceState();
                        return;
                    case Code.ERROR_REAR_CAMERA_OFFLINE:
                        if(mSwitchCameraBtn != null && mSwitchCameraBtn.getVisibility() != View.GONE){
                            mSwitchCameraBtn.setVisibility(View.GONE);
                        }
                        ToastUtil.showToastShort(getString(R.string.rear_camera_offline));
                        syncDeviceState();
                        return;
                    case Code.ERROR_RT_STREAM_OPEN_FAILED:
                        closeRTS();
                        return;
                    default:
                        Dbug.w(tag, "topic="+data.getTopic() + ", reason : " + Code.getCodeDescription(data.getErrorType()));
                        return;
                }
            }
            Dbug.e(tag, "topic=" + data.getTopic());
            int port = RTS_UDP_PORT;
            switch (topic) {
                case Topic.OPEN_REAR_RTS:
                    port = RTS_UDP_REAR_PORT;
                    boolean isAutoRearCamera = PreferencesHelper.getSharedPreferences(mApplication).getBoolean(AppUtils.getAutoRearCameraKey(mApplication.getUUID()), false);
                    if(isAutoRearCamera){
                        PreferencesHelper.putBooleanValue(mApplication, AppUtils.getAutoRearCameraKey(mApplication.getUUID()), false);
                    }
                case Topic.OPEN_FRONT_RTS:
                    Dbug.i(tag, "Open result:" + data);
                    if(null != data.getParams()) {
                        int width, height;
                        int format = -1;
                        width = height = 0;
                        boolean isFrontCamera = port == RTS_UDP_PORT;
                        String rtsWidth = data.getParams().get(TopicKey.WIDTH);
                        String rtsHeight = data.getParams().get(TopicKey.HEIGHT);
                        String rtsFormat = data.getParams().get(TopicKey.FORMAT);
                        if (!TextUtils.isEmpty(rtsWidth) && TextUtils.isDigitsOnly(rtsWidth)) {
                            width = Integer.valueOf(rtsWidth);
                        }
                        if (!TextUtils.isEmpty(rtsHeight) && TextUtils.isDigitsOnly(rtsHeight)) {
                            height = Integer.valueOf(rtsHeight);
                        }
                        if (!TextUtils.isEmpty(rtsFormat) && TextUtils.isDigitsOnly(rtsFormat)) {
                            format = Integer.valueOf(rtsFormat);
                        }

                        int mode = mApplication.getDeviceDesc().getNetMode();
                        if (mode == Stream.Protocol.UDP_MODE || mRealtimeStream == null) {
                            createStream(Stream.Protocol.UDP_MODE, port);///Try to open UDP stream
                        }
                        if (format == DeviceClient.RTS_JPEG) {
                            mRealtimeStream.setResolution(width, height);
                        }
                        if (isFrontCamera) {
                            mRealtimeStream.setFrameRate(mApplication.getDeviceSettingInfo().getFrontRate());
                            mRealtimeStream.setSampleRate(mApplication.getDeviceSettingInfo().getFrontSampleRate());
                        } else {
                            mRealtimeStream.setFrameRate(mApplication.getDeviceSettingInfo().getRearRate());
                            mRealtimeStream.setSampleRate(mApplication.getDeviceSettingInfo().getRearSampleRate());
                        }
                        initPlayer(SDP_URL);
                        updateResolutionUI(port == RTS_UDP_REAR_PORT, width, height);

                        checkCameraType();
                    }
                    break;
                case Topic.CLOSE_PULL_RT_STREAM:
                case Topic.CLOSE_RT_STREAM:
                    if (null != data.getParams()){
                        boolean closeRTS = TopicParam.SURE.equals(data.getParams().get(TopicKey.STATUS));
                        Dbug.w(tag, "close rt stream result : " + closeRTS + ", isAdjustResolution : " +isAdjustResolution+", " + isSwitchCamera);
                        if(closeRTS && (isAdjustResolution || isSwitchCamera)){
                            if (isAdjustResolution) isAdjustResolution = false;
                            if (isSwitchCamera) isSwitchCamera = false;
                            dismissWaitingDialog();
                            openRTS();
                        }
                    }
                    break;
                case Topic.VIDEO_CTRL:  // video start
                    if (null == data.getParams()) {
                        return;
                    }
                    String state = data.getParams().get(TopicKey.STATUS);
                    if (!TextUtils.isEmpty(state)) {
                        boolean isRecord = TopicParam.OPEN.equals(state);
                        if (isRecord) {
                            recordStatus = STATUS_RECORDING;
                            int currentRecordLevel = getCameraLevel(mApplication.getDeviceSettingInfo().getCameraType());
                            int currentStreamLevel;
                            if (isRtspEnable) {
                                currentStreamLevel = AppUtils.getRtspResolutionLevel();
                            } else {
                                currentStreamLevel = AppUtils.getStreamResolutionLevel();
                            }
                            if (currentRecordLevel == RTS_LEVEL_FHD && currentStreamLevel == RTS_LEVEL_FHD) {
                                switchStreamResolution(RTS_LEVEL_HD);
                                mAdjustResolutionBtn.setImageResource(getLevelResId(RTS_LEVEL_HD));
                            }
                        } else {
                            recordStatus = STATUS_NOT_RECORD;
                        }
                        handlerVideoUI();
                        Dbug.w(tag, "state=" + state + ", dir=" + data.getParams().get(TopicKey.PATH));
                    }
                    break;
                case Topic.VIDEO_FINISH: // video finish
                    if (null == data.getParams()) {
                        return;
                    }
                    String videoState = data.getParams().get(TopicKey.STATUS);
                    boolean isRecording = TopicParam.OPEN.equals(videoState);
                    if (isRecording) {
                        recordStatus = STATUS_RECORDING;
                    } else {
                        recordStatus = STATUS_NOT_RECORD;
                    }
                    String desc = data.getParams().get(TopicKey.DESC);
                    if (!TextUtils.isEmpty(desc)) {
                        desc = desc.replaceAll("\\\\", "");
                        Dbug.w(tag, "-VIDEO_FINISH- desc = " + desc);
                        FileInfo fileInfo = JSonManager.parseFileInfo(desc);
                        if (fileInfo != null) {
                            // // TODO: 增加视频数据
                            int cameraType = DeviceClient.CAMERA_FRONT_VIEW;
                            if (CAMERA_TYPE_REAR.equals(fileInfo.getCameraType())) {
                                cameraType = DeviceClient.CAMERA_REAR_VIEW;
                            }
                            if (mFileInfoList == null) {
                                Dbug.e(tag, "Maybe you never known why mFileInfoList is null");
                                break;
                            }
                            if (fileInfo.isVideo() && (cameraType == mApplication.getDeviceSettingInfo().getCameraType())) {
                                int index = 0;
                                for (; index < mFileInfoList.size(); index++) {
                                    if (fileInfo.getStartTime().getTimeInMillis() >= mFileInfoList.get(index).getStartTime().getTimeInMillis())
                                        break;
                                }
                                if (index <= mFileInfoList.size()) {
                                    Dbug.w(tag, "-insert fileInfo ");
                                    mFileInfoList.add(index, fileInfo);
                                    //isInsertFileInfo = true;
                                    List<FileInfo> tempFileInfos = new ArrayList<>();
                                    tempFileInfos.add(fileInfo);
                                    requestVideoThumbnail(tempFileInfos);
                                    FileInfo selectedFileInfo = mAdapter.getItem(mCoverFlowCarousel.getSelectedPos());
                                    if (selectedFileInfo != null) {
                                        playbackSeekbar.setFileInfo(selectedFileInfo);
                                        mPositionTime.setText(yyyyMMddHHmmss.format(selectedFileInfo.getStartTime().getTimeInMillis()));
                                    } else {
                                        Dbug.e(tag, "Ill-considered: selectedFileInfo is null");
                                    }
                                }
                            }
                        }
                    }
                    break;
                case Topic.PHOTO_CTRL:
                    if (null == data.getParams()) {
                        return;
                    }
                    shootSound();
                    //flashScreen();
                    String photoDesc = data.getParams().get(TopicKey.DESC);
                    if (!TextUtils.isEmpty(photoDesc)) {
                        photoDesc = photoDesc.replaceAll("\\\\", "");
                        Dbug.w(tag, "-PHOTO_CTRL- photoDesc = " + photoDesc);
                    }
                    break;
                case Topic.FRONT_MEDIA_FILE_LIST:
                case Topic.REAR_MEDIA_FILE_LIST:
                    if (data.getParams() == null) {
                        Dbug.e(tag, "Param is null");
                        return;
                    }
                    //Dbug.e(tag, "Param =" + data.getParams().toString());
                    String type = data.getParams().get(TopicKey.TYPE);
                    if (TopicParam.NONE.equals(type)) {
                        mLoadingDialog.setProgressBarVisibility(View.GONE);
                        mLoadingDialog.setContent(R.string.device_no_videos);
                        return;
                    }
                    String path = data.getParams().get(TopicKey.PATH);
                    if(!TextUtils.isEmpty(path)) {
                        int cameraType = AppUtils.getCameraType(path);
                        if (cameraType == mApplication.getDeviceSettingInfo().getCameraType()) {
                            String ip = ClientManager.getClient().getAddress();
                            String url = AppUtils.formatUrl(ip, DEFAULT_HTTP_PORT, path);
                            Dbug.w(tag, "url=" + url);
                            HttpManager.downloadFile(url, new Callback() {
                                @Override
                                public void onFailure(@NonNull Call call, @NonNull IOException e) {
                                    Dbug.e(tag, "Error:" + e.getMessage());
                                    if (mLoadingDialog != null && mLoadingDialog.isShowing()) {
                                        mLoadingDialog.dismiss();
                                    }
                                }

                                @Override
                                public void onResponse(@NonNull Call call, @NonNull okhttp3.Response response) throws IOException {
                                    Dbug.i(tag, "onResponse code = " + response.code());
                                    if (response.code() == 200) {
                                        ResponseBody responseBody = response.body();
                                        if (responseBody != null) {
                                            String content = new String(responseBody.bytes());
                                            if (!TextUtils.isEmpty(content)) {
//                                        Dbug.i(tag, "content=" + content);
                                                tryToParseData(content);
                                            }
                                        }
                                    }else{
                                        dismissWaitingDialog();
                                        showErrorDialog("request video list failed.");
                                    }
                                    response.close();
                                }
                            });
                        }
                    }
                    break;
                case Topic.VIDEO_CONTENT_THUMBNAILS:
                    Dbug.e(tag, "topic->" + "VIDEO_CONTENT_THUMBNAILS->" + "create");
                case Topic.MULTI_VIDEO_COVER:
                    if (null == data.getParams()) {
                        Dbug.e(tag, "getParams is null 1");
                        return;
                    }
                    if (TopicParam.START.equals(data.getParams().get(TopicKey.STATUS))) {
                        if (mVideoThumbnail == null) {
                            mVideoThumbnail = ThumbnailManager.getInstance();
                        }
                        Dbug.e(tag, "topic->" + "MULTI_VIDEO_COVER->" + "create");
                        mVideoThumbnail.create(THUMBNAIL_TCP_PORT, ClientManager.getClient().getAddress());
                        mVideoThumbnail.setOnFrameListener(new OnFrameListener() {
                            @Override
                            public void onFrame(final byte[] data, final PictureInfo mediaInfo) {
                                if (mediaInfo != null)
                                    Dbug.i(tag, "mediaInfo=" + mediaInfo+ ", time:" + yyyyMMddHHmmss.format(mediaInfo.getTime()));
                                if (mediaInfo != null && !TextUtils.isEmpty(mediaInfo.getPath())
                                        && (mediaInfo.getPath().endsWith(".AVI") || mediaInfo.getPath().endsWith(".avi"))) {
                                    saveBitmapAndUpdateUI(data);
                                    return;
                                }
                                if (mFrameCodec == null) {
                                    mFrameCodec = new FrameCodec();
                                    mFrameCodec.setOnFrameCodecListener(mOnFrameCodecListener);
                                }
                                if (data != null && mediaInfo != null) {
                                    //  Dbug.w(tag, "1 mediaInfo=" + mediaInfo);
                                    int w = mediaInfo.getWidth();
                                    int h = mediaInfo.getHeight();
                                    boolean ret = mFrameCodec.convertToJPG(data, w <= 0 ? 640 : w,
                                            h <= 0 ? 480 : h, TextUtils.isEmpty(mediaInfo.getPath()) ? "no path" : mediaInfo.getPath());
                                    if (!ret) {
                                        thumbnailRequestQueue.poll();
                                        if (thumbnailRequestQueue.isEmpty()) {
                                            stopThumbnailReceive();
                                        }
                                    }
                                    Dbug.w(tag, "-convertToJPG- ret=" + ret);
                                } else {
                                    Dbug.e(tag, "frame codec data is null");
                                    thumbnailRequestQueue.poll();
                                    if (thumbnailRequestQueue.isEmpty()) {
                                        stopThumbnailReceive();
                                    }
                                }
                            }
                        });
                    } else if (TopicParam.FINISH.equals(data.getParams().get(TopicKey.STATUS))) {
                        Dbug.i(tag, "topic->" + "MULTI_VIDEO_COVER->" + "finish");
                        if (mLoadingDialog != null && mLoadingDialog.isShowing()) {
                            mLoadingDialog.dismiss();
                        }
                    } else {
                        Dbug.e(tag, data.getParams().toString());
                    }
                    break;
                case Topic.TF_STATUS:
                    if (null == data.getParams()) {
                        return;
                    }
                    if (TopicParam.TF_ONLINE.equals(data.getParams().get(TopicKey.ONLINE))) {
                        mPositionTime.setVisibility(View.VISIBLE);
                        tvAutoPlayTip.setVisibility(View.VISIBLE);
                        playbackSeekbar.setVisibility(View.VISIBLE);
                        requestFileMsgText();
                    } else {
                        if (recordStatus == STATUS_RECORDING)
                            hideVideoUI();
                        stopLocalRecording();
                        handleTFOffline();
                        mHandler.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                dismissWaitingDialog();
                            }
                        }, 1000);
                    }
                    break;
                case Topic.FILES_DELETE:
                    if (null == data.getParams()) {
                        Dbug.e(tag, "FILES_DELETE: data param is null");
                        return;
                    }
                    String delPath = data.getParams().get(TopicKey.PATH);
                    if (TextUtils.isEmpty(delPath))
                    {
                        Dbug.e(tag, "Delete path is null");
                        return;
                    }
                    if (mFileInfoList == null || mFileInfoList.size() <= 0) {
                        Dbug.e(tag, "mFileInfoList error");
                        return;
                    }
                    if (mAdapter == null) {
                        Dbug.e(tag, "adapter error");
                        return;
                    }
                    Dbug.e(tag, "22 mFileInfoList size=" +mFileInfoList.size() + ", " +mAdapter.getItemCount() + ", mReady2DeleteList=" + mReady2DeleteList.size()
                            + ", list size=" + JSonManager.getInstance().getInfoList().size());
                    if (AppUtils.judgeFileType(delPath) == FILE_TYPE_VIDEO) {
                        for (int index = 0; index < mFileInfoList.size(); index++) {
                            FileInfo fileInfo = mFileInfoList.get(index);
                            if (delPath.equals(fileInfo.getPath())) {
                                mFileInfoList.remove(index);
                                JSonManager.getInstance().getInfoList().remove(index);
                                mAdapter.remove(index);
                                mAdapter.notifyDataSetChanged();
                                //update video thumbnail when deleted all visibility
                                if (mAdapter.getItemCount() < IConstant.PAGE_SIZE/2 && mFileInfoList.size() > 0 && !isDeleteAll) {
                                    int pos = mFileInfoList.size() > IConstant.PAGE_SIZE ? IConstant.PAGE_SIZE : mFileInfoList.size();
                                    //请求视频封面
                                    requestVideoThumbnail(mFileInfoList.subList(mAdapter.getItemCount(), pos));
                                }
                                if (mReady2DeleteList.size() > 0)
                                    mReady2DeleteList.remove(delPath);
                                mHandler.postDelayed(new Runnable() {
                                    @Override
                                    public void run() {
                                        int selected = mCoverFlowCarousel.getSelectedPos();
                                        if (selected > mFileInfoList.size()) {
                                            selected = mFileInfoList.size() - 1;
                                        }
                                        if (mFileInfoList.size() > 0 && mFileInfoList.size() == selected)
                                            mCoverFlowCarousel.getCoverFlowLayout().scrollToPosition(selected - 1);
                                        if (mFileInfoList.size() == 0)
                                            mCoverFlowCarousel.setAdapter(mAdapter);
                                        FileInfo fileInfo = mAdapter.getItem(selected);
                                        if (fileInfo == null) {
                                            dismissWaitingDialog();
                                            return;
                                        }
                                        Dbug.i(tag, "mFileInfoList selected file -> name=" + fileInfo.getName() + "time=" + fileInfo.getCreateTime() + ", selected=" + selected);
                                        handlerFileLockState(fileInfo);
                                        playbackSeekbar.setBrowsePostion(selected);
                                        playbackSeekbar.setFileInfo(fileInfo);
                                        playbackSeekbar.setFileInfoCount(mAdapter.getItemCount());
                                        mPositionTime.setText(yyyyMMddHHmmss.format(fileInfo.getStartTime().getTimeInMillis()));
                                        mHandler.postDelayed(new Runnable() {
                                            @Override
                                            public void run() {
                                                dismissWaitingDialog();
                                            }
                                        }, 1000);
                                    }
                                }, 300);
                                break;
                            }// else Dbug.w(tag, "Not the same:delPath=" + delPath +", getPath=" + fileInfo.getPath());
                        }
                    } else Dbug.e(tag, "delPath is not video type:" + delPath);
                    if (mReady2DeleteList.size() <= 0 &&  isDeleteAll) {
                        isDeleteAll = false;
                    }
                    break;
                case Topic.RT_TALK_CTL:
                    if (null != data.getParams()) {
                        isRtVoiceOpen = TopicParam.OPEN.equals(data.getParams().get(TopicKey.STATUS));
                        if (isRtVoiceOpen) {
                            if (mAudioManager == null) {
                                mAudioManager = AudioRecordManager.getInstance();
                                mAudioManager.setRecordListener(PlaybackActivity.this);
                            }

                            int ret = mAudioManager.startRecord();
                            switch (ret) {
                                case AudioRecordManager.START_RECORD_OK:
                                    intercomManager = IntercomManager.getInstance(ClientManager.getClient().getAddress());
                                    intercomManager.initSendThread();
                                    intercomManager.setOnSendStateListener(PlaybackActivity.this);
                                    break;
                                case AudioRecordManager.ERR_AUDIO_IS_RECORDING:
                                    break;
                                case AudioRecordManager.ERR_SD_CARD_NOT_EXIST:
                                    break;
                            }
                        } else {
                            if (mAudioManager != null) {
                                mAudioManager.stopRecord();
                            }
                            if (intercomManager != null) {
                                intercomManager.stopSendDataThread();
                            }
                        }
                        handlerRTVoiceUI();
                    }
                    break;
                case Topic.PULL_VIDEO_STATUS:
                    if (null != data.getParams()) {
                        if (mHandler != null) {
                            mHandler.postDelayed(new Runnable() {
                                @Override
                                public void run() {
                                    if (!mApplication.getDeviceSettingInfo().isExistRearView()) {
                                        Dbug.w(tag, "is playing " + isPlaying() + ", mCameraType=" + mCameraType);
                                        if (isPlaying() && mCameraType == DeviceClient.CAMERA_REAR_VIEW) {
                                            closeRTS();
                                            if(mHandler != null){
                                                mHandler.postDelayed(new Runnable() {
                                                    @Override
                                                    public void run() {
                                                        openRTS();
                                                    }
                                                }, 250);
                                            }
                                        }
                                    }else{
                                        boolean isAutoRearCamera = PreferencesHelper.getSharedPreferences(mApplication).getBoolean(AppUtils.getAutoRearCameraKey(mApplication.getUUID()), false);
                                        if(isAutoRearCamera && mCameraType != DeviceClient.CAMERA_REAR_VIEW){
                                            if(mSwitchCameraBtn != null){
                                                mSwitchCameraBtn.performClick();
                                            }
                                        }
                                    }
                                    syncDeviceState();
                                }
                            }, 100);
                        }
                    }
                    break;
                case Topic.FILE_LOCK:
                    if (null != data.getParams()) {
                        boolean isLock = TopicParam.LOCKED.equals(data.getParams().get(TopicKey.STATUS));
                        FileInfo fileInfo = mAdapter.getItem(mCoverFlowCarousel.getSelectedPos());
                        if (fileInfo != null) {
                            if (isLock) {
                                fileInfo.setType(FILE_TYPE_SOS);
                            } else {
                                fileInfo.setType(FILE_TYPE_NORMAL);
                            }
                            handlerFileLockState(fileInfo);
                            if (mHandler != null) {
                                mHandler.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        mAdapter.notifyDataSetChanged();
                                    }
                                });
                            }
                        }
                    }
                    break;
                case Topic.CYC_SAVE_VIDEO:
                    if(null != data.getParams()){
                        boolean result = TopicParam.SURE.equals(data.getParams().get(TopicKey.STATUS));
                        Dbug.w(tag, "cyc save video : " + result);
                        if(!result){
                            ToastUtil.showToastShort(getString(R.string.cyc_save_video_failed));
                        }
                    }
                    break;
            }
        }
    };

    private void stopThumbnailReceive() {
        Dbug.i(tag, "--------------------------------------stopThumbnailReceive--------------------------");
        if (mVideoThumbnail != null) {
            mVideoThumbnail.close();
        }
        //检测是否因为失败没有接受的封面图，有就二次请求
        List<FileInfo> fileInfoList = thumbnailRequestQueue.getFileInfos();
        if (fileInfoList != null && fileInfoList.size() > 0) {
            requestVideoThumbnail(fileInfoList);
        }
    }

    private void handleTFOffline() {
        if (playbackSeekbar.getMode() == PlaybackSeekbar.REAL_TIME_STREAM_MODE) {
            if(mFileInfoList != null){
                mFileInfoList.clear();
            }
            mAdapter.clear();
            mCoverFlowCarousel.setAdapter(mAdapter);
            playbackSeekbar.setFileInfoCount(0);
            thumbnailRequestQueue.clear();
            mPositionTime.setVisibility(View.INVISIBLE);
            tvAutoPlayTip.setVisibility(View.INVISIBLE);
            playbackSeekbar.setVisibility(View.INVISIBLE);
        } else {
            Dbug.w(tag, "onBackPressed ...........>");
            onBackPressed();
        }
    }

    private void tryToParseData(String s) {
        if (TextUtils.isEmpty(s)) {
            Dbug.e(tag, "tryToParseData: desc is empty!!");
            return;
        }
        JSonManager.getInstance().parseJSonData(s, new OnCompletedListener<Boolean>() {
            @Override
            public void onCompleted(Boolean state) {
                Dbug.i(tag, "data state=" + state);
                if (state) {
                    mFileInfoList = JSonManager.getInstance().getVideoInfoList();
                    if (mFileInfoList == null || mFileInfoList.size() <= 0) {
                        Dbug.e(tag, "video fileInfoList is 0");
                        if (mLoadingDialog != null && mLoadingDialog.isShowing()) {
                            mLoadingDialog.dismiss();
                        }
                        return;
                    }
                    Dbug.d(tag, "total thumbnail count =" + mFileInfoList.size());
                    AppUtils.descSortWay(mFileInfoList);
                    int pos = mFileInfoList.size() > IConstant.PAGE_SIZE ? IConstant.PAGE_SIZE : mFileInfoList.size();
                    //请求视频封面
                    requestVideoThumbnail(mFileInfoList.subList(0, pos));
                } else {
                    if (mLoadingDialog != null && mLoadingDialog.isShowing()) {
                        mLoadingDialog.dismiss();
                    }
                }
            }
        });
    }

    private void requestVideoThumbnail(List<FileInfo> fileInfoList) {
        if (fileInfoList != null) {
            Dbug.e(tag, "requestVideoThumbnail " + fileInfoList.size());
            final List<String> list = new ArrayList<>();
            for (FileInfo fileInfo : fileInfoList) {
                String cameraDir = checkCameraDir(fileInfo);
                String path = AppUtils.splicingFilePath(mApplication.getAppName(), mApplication.getUUID(), cameraDir, IConstant.DIR_THUMB)
                        + File.separator + AppUtils.getVideoThumbName(fileInfo);
                ThumbnailInfo thumbnailInfo = new ThumbnailInfo();
                thumbnailInfo.setCameraType(fileInfo.getCameraType());
                thumbnailInfo.setPath(fileInfo.getPath());
                thumbnailInfo.setName(fileInfo.getName());
                thumbnailInfo.setVideo(true);
                thumbnailInfo.setDuration(fileInfo.getDuration());
                thumbnailInfo.setSaveUrl(path);
                thumbnailInfo.setStartTime(fileInfo.getStartTime());
                thumbnailInfo.setCreateTime(fileInfo.getCreateTime());
                thumbnailInfo.setEndTime(fileInfo.getEndTime());
                thumbnailInfo.setType(fileInfo.getType());
                mAdapter.addData(thumbnailInfo);
                if (!AppUtils.checkFileExist(path)) {
                    list.add(fileInfo.getPath());
                    thumbnailRequestQueue.put(thumbnailInfo, false);
                } else {
                    Dbug.e(tag, "fileInfo has save ->" + thumbnailInfo.getSaveUrl());
                }
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        playbackSeekbar.setFileInfoCount(mAdapter.getItemCount());
                        updateCoverFlowCarousel();
                    }
                });
            }
            if (list.size() != 0) {
                ClientManager.getClient().tryToRequestVideoCover(list, new SendResponse() {
                    @Override
                    public void onResponse(Integer code) {
                        if (code != SEND_SUCCESS) {
                            Dbug.e(tag, "Send failed");
                            thumbnailRequestQueue.clear();
                        }
                    }
                });
            } else {
                Dbug.i(tag, "request list =null");
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        if (mLoadingDialog != null && mLoadingDialog.isShowing()) {
                            mLoadingDialog.dismiss();
                        }
                    }
                });
            }
        }
    }

    private String checkCameraDir(FileInfo fileInfo) {
        String cameraDir = DIR_FRONT;
        if (fileInfo != null) {
            String camera = fileInfo.getCameraType();
            if (CAMERA_TYPE_REAR.equals(camera)) {
                cameraDir = DIR_REAR;
            }
        }
        return cameraDir;
    }

    private void requestVideoContentThumbnail(final FileInfo fileInfo, int offset, final int number) {
        if (fileInfo != null) {
            Dbug.e(tag, "requestVideoContentThumbnail " + fileInfo.getPath() + ", offset " + offset+", num " +number);
            ClientManager.getClient().tryToRequestVideoContentThumbnail(
                    fileInfo.getPath(), offset, 1000, number, new SendResponse() {
                        @Override
                        public void onResponse(Integer code) {
                            if (code != SEND_SUCCESS) {
                                Dbug.e(tag, "Send failed");
                            } else {
                                Dbug.e(tag, "Send success");
                                for (int i = 0; i < number; i++) {
                                    thumbnailRequestQueue.put(fileInfo, true);
                                }
                            }
                        }
                    });
        }
    }

    private void showPlaybackDialog(String path, long time) {
        mHandler.removeCallbacks(autoPlayRunnable);
        Bundle args = new Bundle();
        args.putString(VIDEO_PATH, path);
        args.putLong(VIDEO_CREATE_TIME, time);
        args.putInt(VIDEO_OFFSET, playbackSeekbar.getOffset());
        Intent intent = new Intent(this, PlaybackDialogActivity.class);
        intent.putExtras(args);
        startActivity(intent);
        tvAutoPlayTip.setVisibility(View.INVISIBLE);
    }

    private void showPopupMenu(View view){
        String[] levels;
        int currentLevel;
        if (isRtspEnable) {
            currentLevel = AppUtils.getRtspResolutionLevel();
            levels = AppUtils.getRtspResolutions();
        } else {
            currentLevel = AppUtils.getStreamResolutionLevel();
            levels = AppUtils.getStreamResolutions();
        }
        if (levels == null || levels.length <= 1) {
            Dbug.e(tag, "showPopupMenu <=1");
            return;
        }

        int currentRecordLevel = getCameraLevel(mApplication.getDeviceSettingInfo().getCameraType());
        Dbug.w(tag, "levels="+levels.length +", currentRecordLevel="+currentRecordLevel+ ", currentLevel====== " + currentLevel);
        Map<Integer, Integer> resMap = new HashMap<>();
        for (String str : levels){
            if(!TextUtils.isEmpty(str) && TextUtils.isDigitsOnly(str)){
                int rtsLevel = Integer.valueOf(str);
                if (recordStatus != STATUS_RECORDING) {
                    if (rtsLevel != currentLevel) {
                        resMap.put(rtsLevel, getLevelResId(rtsLevel));
                    }
                } else {
                    if (currentRecordLevel == RTS_LEVEL_FHD && rtsLevel < RTS_LEVEL_FHD) {//Record:1080
                        if (rtsLevel != currentLevel) {
                            resMap.put(rtsLevel, getLevelResId(rtsLevel));
                        }
                    } else if (currentRecordLevel < RTS_LEVEL_FHD) {//Record: vga/720
                        if (rtsLevel != currentLevel) {
                            resMap.put(rtsLevel, getLevelResId(rtsLevel));
                        }
                    }
                }
            }
        }
        dismissPopMenu();
        popupMenu = new PopupMenu(mApplication, resMap);
        popupMenu.setOnPopItemClickListener(mOnPopItemClickListener);
        popupMenu.showAsRight(view);
    }

    private void dismissPopMenu(){
        if (popupMenu != null) {
            if(popupMenu.isShowing()){
                popupMenu.dismiss();
            }
            popupMenu = null;
        }
    }

    private PopupMenu.OnPopItemClickListener mOnPopItemClickListener = new PopupMenu.OnPopItemClickListener() {
        @Override
        public void onItemClick(final int level, final Integer resId, int index) {
            switchStreamResolution(level);
        }
    };

    private void switchStreamResolution(int level) {
        if(isPlaying()){
            closeRTS();
        }

        if (isRtspEnable) {
            AppUtils.saveRtspResolutionLevel(level);
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    openRTS();
                }
            }, 200);
        } else {
            isAdjustResolution = true;
            AppUtils.saveStreamResolutionLevel(level);
            showWaitingDialog();
        }
    }

    private void showOperationFileDialog(int op, FileInfo selectedFileInfo) {
        if (selectedFileInfo != null) {
            if (operationFileDialog != null && operationFileDialog.isShowing()) {
                operationFileDialog.dismiss();
                operationFileDialog = null;
            }
            switch (op) {
                case OP_DELETE_FILE:
                    operationFileDialog = NotifyDialog.newInstance(R.string.dialog_warning, R.string.delete_emergency_video_tip,
                            R.string.dialog_cancel, R.string.dialog_confirm, new NotifyDialog.OnNegativeClickListener() {
                                @Override
                                public void onClick() {
                                    if (operationFileDialog != null && operationFileDialog.isShowing()) {
                                        operationFileDialog.dismiss();
                                        operationFileDialog = null;
                                    }
                                }
                            }, new NotifyDialog.OnPositiveClickListener() {
                                @Override
                                public void onClick() {
                                    Bundle bundle = operationFileDialog.getBundle();
                                    if (bundle != null) {
                                        FileInfo fileInfo = (FileInfo) bundle.getSerializable(KEY_FILE_INFO);
                                        deleteFile(fileInfo);
                                    }
                                    if (operationFileDialog != null && operationFileDialog.isShowing()) {
                                        operationFileDialog.dismiss();
                                        operationFileDialog = null;
                                    }
                                }
                            });
                    break;
                case OP_LOCK_FILE:
                    boolean isLock = (selectedFileInfo.getType() == FILE_TYPE_SOS);
                    int content;
                    if (isLock) {
                        content = R.string.unlock_file_tip;
                    } else {
                        content = R.string.lock_file_tip;
                    }
                    operationFileDialog = NotifyDialog.newInstance(R.string.dialog_tips, content,
                            R.string.dialog_cancel, R.string.dialog_confirm, new NotifyDialog.OnNegativeClickListener() {
                                @Override
                                public void onClick() {
                                    if (operationFileDialog != null && operationFileDialog.isShowing()) {
                                        operationFileDialog.dismiss();
                                        operationFileDialog = null;
                                    }
                                }
                            }, new NotifyDialog.OnPositiveClickListener() {
                                @Override
                                public void onClick() {
                                    Bundle bundle = operationFileDialog.getBundle();
                                    if (bundle != null) {
                                        FileInfo fileInfo = (FileInfo) bundle.getSerializable(KEY_FILE_INFO);
                                        if (fileInfo != null) {
                                            boolean isLock = (fileInfo.getType() == FILE_TYPE_SOS);
                                            ClientManager.getClient().tryToFileLock(fileInfo.getPath(), !isLock, new SendResponse() {
                                                @Override
                                                public void onResponse(Integer code) {

                                                }
                                            });
                                        }
                                    }
                                    if (operationFileDialog != null && operationFileDialog.isShowing()) {
                                        operationFileDialog.dismiss();
                                        operationFileDialog = null;
                                    }
                                }
                            });
                    break;
            }
            if (operationFileDialog != null) {
                Bundle bundle = new Bundle();
                bundle.putSerializable(KEY_FILE_INFO, selectedFileInfo);
                operationFileDialog.setBundle(bundle);
                if (!operationFileDialog.isShowing()) {
                    operationFileDialog.show(getSupportFragmentManager(), "operation_dialog");
                }
            }
        }
    }

    private void deleteFile(FileInfo fileInfo) {
        if (fileInfo != null) {
            mReady2DeleteList.clear();
            mReady2DeleteList.add(fileInfo.getPath());
            ClientManager.getClient().tryToDeleteFile(mReady2DeleteList, new SendResponse() {
                @Override
                public void onResponse(Integer code) {
                    if(code == SEND_SUCCESS){
                        showWaitingDialog();
                    }else{
                        dismissWaitingDialog();
                    }
                }
            });
        } else {
            Dbug.e(tag, "delete file failed");
        }
    }

    private void deleteAllFiles() {
        mReady2DeleteList.clear();
        for (Iterator<FileInfo> iterator = JSonManager.getInstance().getVideoInfoList().iterator(); iterator.hasNext();)
            mReady2DeleteList.add(iterator.next().getPath());
        if (mReady2DeleteList.size() > 0) {
            ClientManager.getClient().tryToDeleteFile(mReady2DeleteList, new SendResponse() {
                @Override
                public void onResponse(Integer code) {
                    if(code == SEND_SUCCESS){
                        isDeleteAll = true;
                        showWaitingDialog();
                    }else{
                        dismissWaitingDialog();
                    }
                }
            });
        } else Dbug.e(tag, "delete files failed");
    }

    private void showWaitingDialog(){
        if(!isDestroyed()){
            if(mWaitingDialog == null){
                mWaitingDialog = new WaitingDialog();
                mWaitingDialog.setNotifyContent(getString(R.string.deleting_tip));
            }
            if(!mWaitingDialog.isShowing()){
                mWaitingDialog.show(getSupportFragmentManager(), "waiting_dialog");
            }
        }
    }

    private void dismissWaitingDialog(){
        if(mWaitingDialog != null){
            if(mWaitingDialog.isShowing() && !isDestroyed()){
                mWaitingDialog.dismiss();
            }
            mWaitingDialog = null;
        }
    }

    private void dismissAdjustingDialog(){
        if(mAdjustingDialog != null){
            if(mAdjustingDialog.isShowing() && !isDestroyed()){
                mAdjustingDialog.dismiss();
            }
            mAdjustingDialog = null;
        }
    }

    private void showErrorDialog(String errMsg){
        if(!TextUtils.isEmpty(errMsg)){
            mErrorDialog = NotifyDialog.newInstance(getString(R.string.dialog_tips), errMsg, R.string.dialog_ok,
                    new NotifyDialog.OnConfirmClickListener() {
                        @Override
                        public void onClick() {
                            dismissErrorDialog();
                            onBackPressed();
                        }
                    });
            if (!mErrorDialog.isShowing()) {
                mErrorDialog.show(getSupportFragmentManager(), "ViewDialog");
            }
        }
    }

    private void dismissErrorDialog(){
        if(mErrorDialog != null){
            if(mErrorDialog.isShowing() && !isDestroyed()){
                mErrorDialog.dismiss();
            }
            mErrorDialog = null;
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_MEDIA_PROJECTION) {
            if (resultCode == RESULT_OK && data != null) {
                ClientManager.getClient().tryToStreamingPush(true, 640, 480, 30, new SendResponse() {
                    @Override
                    public void onResponse(Integer code) {
                        if (code == SEND_SUCCESS) {
                            handlerProjectionUI();
                        }
                    }
                });
            }
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

    @Override
    protected void onResume() {
        super.onResume();
        isOnPause = false;
        updateModeUI(playbackMode);
//        if (playbackSeekbar != null) {
//            if (playbackSeekbar.getMode() != PlaybackSeekbar.REAL_TIME_STREAM_MODE) {
//                Dbug.i(tag, "handleAutoPlay 555555555555");
//                handleAutoPlay();
//            }
//        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        isOnPause = true;
        closeRTS();
        if (mRealtimeStream != null) {
            mRealtimeStream.unregisterStreamListener(realtimePlayerListener);
            mRealtimeStream.release();
            mRealtimeStream = null;
        }
        if (isRtVoiceOpen) {
            mVoiceBtn.performClick();
        }
        mHandler.removeCallbacks(autoPlayRunnable);
    }

    @Override
    protected void onStop() {
        super.onStop();
        MainApplication.getApplication().unregisterReceiver(mReceiver);
    }

    @Override
    protected void onDestroy() {
        isOnPause = false;
        dismissPopMenu();
        if(operationFileDialog != null){
            if(operationFileDialog.isShowing()){
                operationFileDialog.dismiss();
            }
            operationFileDialog = null;
        }

        closeRTS();

        dismissErrorDialog();
        dismissWaitingDialog();
        dismissAdjustingDialog();
        super.onDestroy();
        //Dbug.i(tag, "==================onDestroy===============");
        if (null != wakeLock && wakeLock.isHeld()) {
            wakeLock.release();
        }

        if (mVideoThumbnail != null) {
            mVideoThumbnail.close();
        }
        if (mFrameCodec != null) {
            mFrameCodec.setOnFrameCodecListener(null);
            mFrameCodec.destroy();
            mFrameCodec = null;
        }
        ClientManager.getClient().unregisterNotifyListener(onNotifyListener);
        if (mHandler != null) {
            mHandler.removeCallbacksAndMessages(null);
            mHandler = null;
        }
        if (mAudioManager != null) {
            mAudioManager.release();
            mAudioManager = null;
        }
    }

    private void openRTS() {
        if(isPlaying()){
            Dbug.e(tag, "rts is playing, please stop it first.");
            return;
        }

        boolean isDebugOpen = PreferencesHelper.getSharedPreferences(mApplication).getBoolean(IConstant.DEBUG_SETTINGS, false);
        if(isDebugOpen){
            if(mHudView != null){
                if(mHudView.getVisibility() != View.VISIBLE){
                    mHudView.setVisibility(View.VISIBLE);
                    mStreamView.setHudView(mHudView);
                }
            }
            startDebug();
        }else{
            if(mHudView != null){
                if(mHudView.getVisibility() != View.GONE){
                    fps = 0;
                    if(mHandler != null){
                        mHandler.removeMessages(MSG_FPS_COUNT);
                    }
                    mHudView.setVisibility(View.GONE);
                    mStreamView.setHudView(null);
                }
            }
        }

        if (isRtspEnable) {
            initPlayer(AppUtils.getRtspUrl());
            isSwitchCamera = false;
            return;
        }

        int mRTSType = AppUtils.getRtsFormat();
        int cameraType = mApplication.getDeviceSettingInfo().getCameraType();
        int mode =  mApplication.getDeviceDesc().getNetMode();
        if (mode == Stream.Protocol.TCP_MODE) {
            createStream(mode, VIDEO_SERVER_PORT);//For TCP stream mode
        }
        Dbug.i(tag, "open rts...........");
        int level = AppUtils.getStreamResolutionLevel();
        int[] resolution = AppUtils.getRtsResolution(level);
        ClientManager.getClient().tryToOpenRTStream(cameraType, mRTSType, resolution[0], resolution[1], getVideoRate(cameraType), new SendResponse() {
            @Override
            public void onResponse(Integer code) {
                if (code != SEND_SUCCESS) {
                    Dbug.e(tag, "Send failed!!!");
                }
            }
        });
    }

    private void closeRTS() {
        Dbug.i(tag, "close rts................");
        deinitPlayer();

        boolean isDebugOpen = PreferencesHelper.getSharedPreferences(mApplication).getBoolean(IConstant.DEBUG_SETTINGS, false);
        if(isDebugOpen) closeDebug();
        if (!isRtspEnable) {
            if(isPlaying() || isSwitchCamera){
                int cameraTyp = mApplication.getDeviceSettingInfo().getCameraType();
                ClientManager.getClient().tryToCloseRTStream(cameraTyp, new SendResponse() {
                    @Override
                    public void onResponse(Integer code) {
                        if (code != SEND_SUCCESS) {
                            Dbug.e(tag, "Send failed!!!");
                        }
                    }
                });
            }
        }
        stopLocalRecording();

        if (mVideoCapture != null) {
            mVideoCapture.destroy();
            mVideoCapture = null;
        }

        if (mRealtimeStream != null) {
            mRealtimeStream.close();
            mRealtimeStream = null;
        }

        if (mLoadingView != null && mLoadingView.getVisibility() != View.GONE) {
            mLoadingView.setVisibility(View.GONE);
        }
        if(playbackMode == MODE_PREVIEW && mRTSPlayButton != null && mRTSPlayButton.getVisibility() != View.VISIBLE){
            mRTSPlayButton.setVisibility(View.VISIBLE);
        }
    }

    private void initPlayer(String videoPath) {
        if (mStreamView != null && !TextUtils.isEmpty(videoPath)) {
            final Uri uri = Uri.parse(videoPath);
            // init player
            IjkMediaPlayer.loadLibrariesOnce(null);
            IjkMediaPlayer.native_profileBegin("libijkplayer.so");
            isIJKPlayerOpen = true;
            mStreamView.setRealtime(true);
            mStreamView.setVideoURI(uri);
            mStreamView.start();

            mRTSPlayButton.setVisibility(View.GONE);
            mLoadingView.setVisibility(View.VISIBLE);
        } else {
            Dbug.e(tag, "init player fail");
        }
    }

    private void deinitPlayer() {
        Dbug.w(tag, "deinit player");
        if (mStreamView != null) {
            mStreamView.stopPlayback();
            mStreamView.release(true);
            mStreamView.stopBackgroundPlay();
        }
        if (isIJKPlayerOpen) IjkMediaPlayer.native_profileEnd();
        isIJKPlayerOpen = false;
    }

    public void requestCapturePermission() {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            //5.0 之后才允许使用屏幕截图
            ToastUtil.showToastLong(getString(R.string.projection_not_support));
        } else {
            isProjection = true;
            mApplication.getDeviceSettingInfo().setOpenProjection(true);
            MediaProjectionManager mediaProjectionManager = (MediaProjectionManager)getSystemService(Context.MEDIA_PROJECTION_SERVICE);
            if (mediaProjectionManager != null)
                startActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), REQUEST_MEDIA_PROJECTION);
        }
    }

    private boolean isSdOnline() {
        if (!MainApplication.getApplication().isSdcardExist())
            ToastUtil.showToastShort(getResources().getString(R.string.sdcard_offline));
        return MainApplication.getApplication().isSdcardExist();
    }

    private int findFileInfoIndex(FileInfo info) {
        int index = -1;
        if (info != null && mFileInfoList != null) {
            for (int i = 0; i < mFileInfoList.size(); i++) {
                FileInfo info1 = mFileInfoList.get(i);
                if (info1.getName().equals(info.getName())) {
                    index = i;
                    break;
                }
            }
        }
        Dbug.i(tag, "find fileinof index=" + index);
        return index;
    }

    /**
     * 拍照声效
     */
    private void shootSound() {
        AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        int volume = 0;
        if (audioManager != null) volume = audioManager.getStreamVolume(AudioManager.STREAM_ALARM);
        Dbug.i(tag, "volume=:" + volume);

        if (volume != 0) {
            MediaPlayer mMediaPlayer = MediaPlayer.create(this, (R.raw.camera_click));
            mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    if (mp != null) {
                        mp.stop();
                        mp.release();
                    }
                }
            });
            mMediaPlayer.start();
        }
    }

    private void handlerProjectionUI() {
        if (playbackMode != MODE_PREVIEW) return;
        if (mProjectionFlag != null) {
            if (isProjection) {
                mProjectionBtn.setImageResource(R.mipmap.ic_projection_selected);
                mProjectionFlag.setVisibility(View.VISIBLE);
            } else {
                mProjectionFlag.setVisibility(View.GONE);
                mProjectionBtn.setImageResource(R.drawable.drawable_projection);
            }
        }
    }

    private void handlerRTVoiceUI() {
        if (playbackMode != MODE_PREVIEW) return;
        if (isRtVoiceOpen) {
            mVoiceBtn.setImageResource(R.mipmap.ic_hor_voice_selected);
        } else {
            mVoiceBtn.setImageResource(R.drawable.drawable_hor_voice);
        }
    }

    private void handlerVideoUI() {
        if (playbackMode != MODE_PREVIEW) return;
        if (recordStatus == STATUS_RECORDING) {
            showVideoUI();
        } else {
            hideVideoUI();
        }
    }

    private void showVideoUI(){
        if (wakeLock != null) {
            wakeLock.acquire(60*60*60);
        }
        mRecordFlag.setVisibility(View.VISIBLE);
        mVideoBtn.setImageResource(R.mipmap.ic_record_selected);
        Animation alphaAnimation = new AlphaAnimation(1, 0);
        alphaAnimation.setDuration(500);
        alphaAnimation.setInterpolator(new LinearInterpolator());
        alphaAnimation.setRepeatCount(Animation.INFINITE);
        alphaAnimation.setRepeatMode(Animation.REVERSE);
        mRecordFlag.startAnimation(alphaAnimation);
    }

    private void hideVideoUI(){
        if (null != wakeLock && wakeLock.isHeld()) {
            wakeLock.release();
        }
        mRecordFlag.clearAnimation();
        mRecordFlag.setVisibility(View.GONE);
        mVideoBtn.setImageResource(R.drawable.drawable_record_control);
    }

    private void handlerControlBarUI() {
        boolean isShowControlBar = !(centerControlBar != null && centerControlBar.getVisibility() == View.VISIBLE);
        int visible;
        boolean isTfCardOnline = mApplication.isSdcardExist();
        if (isShowControlBar) {
            visible = View.VISIBLE;
            if (topBar != null && topBar.getVisibility() != visible) {
                topBar.setAnimation(AnimationUtils.loadAnimation(this, R.anim.slide_in_top));
                topBar.setVisibility(visible);
            }
            if (leftControlBar != null && leftControlBar.getVisibility() != visible) {
                leftControlBar.setAnimation(AnimationUtils.loadAnimation(this, R.anim.left_enter));
                leftControlBar.setVisibility(visible);
            }
            if (centerControlBar != null && centerControlBar.getVisibility() != visible) {
                centerControlBar.setAnimation(AnimationUtils.loadAnimation(this, R.anim.right_enter));
                centerControlBar.setVisibility(visible);
            }
            if (playbackSeekbar != null && playbackSeekbar.getVisibility() != visible && isTfCardOnline) {
                playbackSeekbar.setAnimation(AnimationUtils.loadAnimation(this, R.anim.slide_in_bottom));
                playbackSeekbar.setVisibility(visible);
            }
        } else {
            visible = View.INVISIBLE;
            if(!isProjection && playbackMode == MODE_PREVIEW) {
                if (topBar != null && topBar.getVisibility() != visible) {
                    topBar.setAnimation(AnimationUtils.loadAnimation(this, R.anim.slide_out_top));
                    topBar.setVisibility(visible);
                }
                if (leftControlBar != null && leftControlBar.getVisibility() != visible) {
                    leftControlBar.setAnimation(AnimationUtils.loadAnimation(this, R.anim.left_exit));
                    leftControlBar.setVisibility(visible);
                }
                if (centerControlBar != null && centerControlBar.getVisibility() != visible) {
                    centerControlBar.setAnimation(AnimationUtils.loadAnimation(this, R.anim.right_exit));
                    centerControlBar.setVisibility(visible);
                }
                if (playbackSeekbar != null && playbackSeekbar.getVisibility() != visible) {
                    playbackSeekbar.setAnimation(AnimationUtils.loadAnimation(this, R.anim.slide_out_bottom));
                    playbackSeekbar.setVisibility(visible);
                }
            }
        }
    }

    private void updateModeUI(int mode) {
        if (playbackMode != mode) {
            playbackMode = mode;
        }
        updateTopTv();
        switch (mode) {
            case MODE_PREVIEW: {
                if (layoutBrowse != null && layoutBrowse.getVisibility() != View.GONE) {
                    layoutBrowse.setVisibility(View.GONE);
                }
                if (mStreamView != null && mStreamView.getVisibility() != View.VISIBLE) {
                    mStreamView.setVisibility(View.VISIBLE);
                }
                if (layoutPreview != null && layoutPreview.getVisibility() != View.VISIBLE) {
                    layoutPreview.setVisibility(View.VISIBLE);
                }
                syncDeviceState();
                if (!isPlaying()) {
                    if (isProjection) {
                        handlerControlBarUI();
                    } else {
                        openRTS();
                    }
                }
                break;
            }
            case MODE_BROWSE: {
                Dbug.i(tag, "updateModeUI");
                closeRTS();
                if (mStreamView != null && mStreamView.getVisibility() != View.INVISIBLE) {
                    mStreamView.setVisibility(View.INVISIBLE);
                }
                if (layoutPreview != null && layoutPreview.getVisibility() != View.GONE) {
                    layoutPreview.setVisibility(View.GONE);
                }
                if (layoutBrowse != null && layoutBrowse.getVisibility() != View.VISIBLE) {
                    layoutBrowse.setVisibility(View.VISIBLE);
                }
                break;
            }
        }
    }

    private void handlerFileLockState(FileInfo selectFileInfo) {
        if (selectFileInfo != null && mLockFileBtn != null) {
            int fileType = selectFileInfo.getType();
            int resId;
            if (fileType == FILE_TYPE_SOS) {
                resId = R.drawable.drawable_unlock;
            } else {
                resId = R.drawable.drawable_lock;
            }
            mLockFileBtn.setImageResource(resId);
        }
    }

    /**
     * 同步设备状态
     */
    private void syncDeviceState() {
        if (playbackMode != MODE_PREVIEW) return;
        DeviceSettingInfo deviceSettingInfo = mApplication.getDeviceSettingInfo();
        if (deviceSettingInfo != null) {
            if (recordStatus != deviceSettingInfo.getRecordState()) {
                recordStatus = deviceSettingInfo.getRecordState();
                handlerVideoUI();
            }
            if (isProjection != deviceSettingInfo.isOpenProjection()) {
                isProjection = deviceSettingInfo.isOpenProjection();
                handlerProjectionUI();
            }
            if (isRtVoiceOpen != deviceSettingInfo.isRTVoice()) {
                isRtVoiceOpen = deviceSettingInfo.isRTVoice();
                handlerRTVoiceUI();
            }
            updateResolutionIcon();
            if (deviceSettingInfo.isExistRearView()) {
                mSwitchCameraBtn.setVisibility(View.VISIBLE);
            } else {
                mSwitchCameraBtn.setVisibility(View.GONE);
            }
        }
    }

    private void updateTopTv() {
        String title;
        if (playbackMode == MODE_PREVIEW) {
            title = getString(R.string.live_preview);
        } else {
            title = getString(R.string.playback);
        }
        String cameraStr = "(" + getString(R.string.front_view) + ")";
        if (mCameraType == DeviceClient.CAMERA_REAR_VIEW) {
            cameraStr = "(" + getString(R.string.rear_view) + ")";
        }
        title += cameraStr;
        tvTop.setText(title);
    }

    private void checkCameraType() {
        int cameraType = mApplication.getDeviceSettingInfo().getCameraType();
        boolean isSwitchCamera = (mCameraType != cameraType);
        if (!isSwitchCamera) {
            return;
        }
        mCameraType = cameraType;
        updateTopTv();
        handleTFOffline();
        if (mHandler != null) {
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    updateResolutionIcon();
                    mPositionTime.setVisibility(View.VISIBLE);
                    tvAutoPlayTip.setVisibility(View.VISIBLE);
                    requestFileMsgText();
                }
            }, 200);
        }
    }

    private IMediaController iMediaController = new IMediaController() {
        @Override
        public void hide() {
        }

        @Override
        public boolean isShowing() {
            return (centerControlBar != null && centerControlBar.getVisibility() == View.VISIBLE);
        }

        @Override
        public void setAnchorView(View view) {

        }

        @Override
        public void setEnabled(boolean enabled) {
            Dbug.i(tag, "setEnabled : " + enabled);
            if (enabled) {
                if (mLoadingView != null && mLoadingView.getVisibility() != View.GONE) {
                    mLoadingView.setVisibility(View.GONE);
                }
            }
        }

        @Override
        public void setMediaPlayer(MediaController.MediaPlayerControl player) {

        }

        @Override
        public void show(int timeout) {
        }

        @Override
        public void show() {

        }

        @Override
        public void showOnce(View view) {

        }
    };

    private View.OnTouchListener mOnTouchListener = new View.OnTouchListener() {
        private int startX;
        private int startY;
        private boolean isClick = true;

        @Override
        public boolean onTouch(View view, MotionEvent event) {
            final float x = event.getX();
            final float y = event.getY();
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN: {
                    startX = (int) x;
                    startY = (int) y;
                    break;
                }
                case MotionEvent.ACTION_UP: {
                    if (Math.abs(x - startX) > threshold || Math.abs(y - startY) > threshold) {
                        isClick = false;
                    }
                    if (isClick) {
                        handlerControlBarUI();
                    }
                    isClick = true;
                    break;
                }
            }
            return true;
        }
    };

    private IMediaPlayer.OnErrorListener mOnErrorListener = new IMediaPlayer.OnErrorListener() {
        @Override
        public boolean onError(IMediaPlayer iMediaPlayer, final int framework_err, final int impl_err) {
            Dbug.e(tag, "Error: framework_err=" + framework_err + ",impl_err=" + impl_err);
            if (framework_err == -10000) {
                mLoadingView.setVisibility(View.GONE);
                return true;
            }
            closeRTS();
            showErrorDialog(getString(R.string.fail_to_play));
            return true;
        }
    };

    /**
     * Listen RTSP state
     */
    private final IMediaPlayer.OnPreparedListener onPreparedListener = new IMediaPlayer.OnPreparedListener() {
        @Override
        public void onPrepared(IMediaPlayer iMediaPlayer) {
            mLoadingView.setVisibility(View.GONE);
        }
    };

    /**
     * Listen RTSP state
     */
    private final IMediaPlayer.OnCompletionListener onCompletionListener = new IMediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(IMediaPlayer iMediaPlayer) {
            mRTSPlayButton.setVisibility(View.VISIBLE);
        }
    };

    private OnRealTimeListener realtimePlayerListener = new OnRealTimeListener() {
        @Override
        public void onVideo(int t, int channel, byte[] data, long sequence, long timestamp) {
            if(isStartDebug && PreferencesHelper.getSharedPreferences(mApplication).getBoolean(IConstant.DEBUG_SETTINGS, false)){
                fps++;
            }
            if (mRecordVideo != null && isRecordPrepared) {
                if (!mRecordVideo.write(t, data))
                    Dbug.e(tag, "Write video failed");
            }
            if (mVideoCapture != null && isCapturePrepared) {
                mVideoCapture.capture(data);
            }
        }

        @Override
        public void onAudio(int t, int channel, byte[] data, long sequence, long timestamp) {
            if (mRecordVideo != null && isRecordPrepared) {
                if (!mRecordVideo.write(t, data))
                    Dbug.e(tag, "Write audio failed");
            }
        }

        @Override
        public void onStateChanged(int state) {
            Dbug.i(tag, "onStateChanged:state=" + state);

            if (state == Stream.Status.STOP) {
                stopLocalRecording();
                if (mRTSPlayButton.getVisibility() != View.VISIBLE) {
                    mRTSPlayButton.setVisibility(View.VISIBLE);
                }
            }
        }

        @Override
        public void onError(int code, String message) {
            Dbug.e(tag, "code=" + code + ", message=" + message);
//            mApplication.showToastShort("player has a error, message : "+ message);
            closeRTS();
        }
    };

    @Override
    public void onRecord(byte[] data, int dB) {
        if (data != null) {
            if (intercomManager != null) {
                intercomManager.send(data);
            }
        }
    }

    @Override
    public void onState(int code, String msg) {
        if (intercomManager != null) {
            intercomManager.stopSendDataThread();
        }
        if (mHandler != null) {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    isRtVoiceOpen = false;
                    handlerRTVoiceUI();
                }
            });
        }
    }

    private int getLevelResId(int level) {
        int res;
        switch (level) {
            case RTS_LEVEL_SD:
                res = R.drawable.drawable_resolution_sd;
                break;
            case RTS_LEVEL_FHD:
                res = R.drawable.drawable_resolution_fhd;
                break;
            default:
                res = R.drawable.drawable_resolution_hd;
                break;
        }
        return res;
    }

    private int getCameraLevel(int cameraType) {
        int level = IConstant.RTS_LEVEL_HD;
        DeviceSettingInfo settingInfo = MainApplication.getApplication().getDeviceSettingInfo();
        if (settingInfo != null) {
            if (cameraType == DeviceClient.CAMERA_REAR_VIEW) {
                level = settingInfo.getRearLevel();
            } else {
                level = settingInfo.getFrontLevel();
            }
        }
        return level;
    }

    private int getVideoRate(int cameraType){
        int rate = 30;
        DeviceSettingInfo settingInfo = MainApplication.getApplication().getDeviceSettingInfo();
        if(settingInfo != null){
            if(cameraType == DeviceClient.CAMERA_REAR_VIEW){
                rate = settingInfo.getRearRate();
            }else{
                rate = settingInfo.getFrontRate();
            }
        }
        return rate;
    }

    private void updateResolutionUI(boolean isRearCamera, int width, int height) {
        if (isAdjustResolution) {
            Dbug.w(tag, "adjust resolution step 006. isRear "+ isRearCamera + ", w " + width +", h " + height);
            int rtsLevel = AppUtils.adjustRtsResolution(width, height);
            if(rtsLevel != getCameraLevel(mApplication.getDeviceSettingInfo().getCameraType())){
                if (isRearCamera) {
                    mApplication.getDeviceSettingInfo().setRearLevel(rtsLevel);
                } else {
                    mApplication.getDeviceSettingInfo().setFrontLevel(rtsLevel);
                }
            }
            isAdjustResolution = false;
            dismissAdjustingDialog();
        }
        updateResolutionIcon();
    }

    private void updateResolutionIcon() {
        int currentLevel;
        String[] levels;
        if (isRtspEnable) {
            currentLevel = AppUtils.getRtspResolutionLevel();
            levels = AppUtils.getRtspResolutions();
        } else {
            currentLevel = AppUtils.getStreamResolutionLevel();
            levels = AppUtils.getStreamResolutions();
        }
        if (levels == null || levels.length <= 0) {
            Dbug.w(tag, "resolutions is null");
            mAdjustResolutionBtn.setVisibility(View.GONE);
        } else {
            mAdjustResolutionBtn.setVisibility(View.VISIBLE);
            mAdjustResolutionBtn.setImageResource(getLevelResId(currentLevel));
            Dbug.i(tag, "updateResolutionIcon currentLevel="+currentLevel);
        }
    }

    private void createStream(int mode, int port) {
        Dbug.i(tag, "createStream==========mode=" + mode);
        if (mode == Stream.Protocol.TCP_MODE || mode == Stream.Protocol.UDP_MODE) {
            if (mRealtimeStream == null) {
                mRealtimeStream = new RealtimeStream(mode);
                mRealtimeStream.registerStreamListener(realtimePlayerListener);
            }
            Dbug.i(tag, "Net mode="+ mode +", is receiving " + mRealtimeStream.isReceiving());
            if (!mRealtimeStream.isReceiving()) {
                if (mode == Stream.Protocol.TCP_MODE) {
                    mRealtimeStream.create(port, ClientManager.getClient().getAddress());
                } else {
                    mRealtimeStream.create(port);
                }
                mRealtimeStream.setSoTimeout(5000);
                mRealtimeStream.useDeviceTimestamp(true);
                mRealtimeStream.configure(RTP_VIDEO_PORT1, RTP_AUDIO_PORT1);
            } else Dbug.w(tag, "stream not receiving");
        } else {
            Dbug.e(tag, "Create stream failed!!!");
        }
    }

    private void showLocalRecordDialog() {
        if(mLocalRecordingDialog == null) {
            mLocalRecordingDialog = NotifyDialog.newInstance(R.string.dialog_tips, R.string.no_card_record_tip,
                    R.string.dialog_cancel, R.string.dialog_confirm, new NotifyDialog.OnNegativeClickListener() {
                        @Override
                        public void onClick() {
                            mLocalRecordingDialog.dismiss();
                        }
                    }, new NotifyDialog.OnPositiveClickListener() {
                        @Override
                        public void onClick() {
                            mLocalRecordingDialog.dismiss();
                            startLocalRecording();
                        }
                    });
            mLocalRecordingDialog.setCancelable(false);
        }
        if(!mLocalRecordingDialog.isShowing()){
            mLocalRecordingDialog.show(getSupportFragmentManager(), "No_Card_Record");
        }
    }

    private void startLocalRecording() {
        if (mRecordVideo == null) {
            mRecordVideo = new VideoRecord();
        }
        mRecordVideo.prepare(true, new OnRecordStateListener() {
            @Override
            public void onPrepared() {
                isRecordPrepared = true;
                showVideoUI();
            }

            @Override
            public void onCompletion(String filePath) {

            }

            @Override
            public void onStop() {
                stopLocalRecording();
                hideVideoUI();
            }

            @Override
            public void onError(String message) {
                Dbug.e(tag, "Record error:" + message);
                stopLocalRecording();
                hideVideoUI();
            }
        });
    }

    private void stopLocalRecording() {
        if (mRecordVideo != null) {
            mRecordVideo.close();
            mRecordVideo = null;
        }
        isRecordPrepared = false;
    }

    private boolean isPlaying() {
        if (isRtspEnable) return mStreamView != null && mStreamView.isPlaying();

        return mRealtimeStream != null && mRealtimeStream.isReceiving();
    }

    private void showDeleteFileDialog() {
        if (mDeleteFileDialog == null) {
            mDeleteFileDialog = NotifyDialog.newInstance(R.string.dialog_tips, R.string.sure_to_delete, true,
                    R.string.dialog_cancel, R.string.dialog_confirm, new NotifyDialog.OnNegativeClickListener() {
                        @Override
                        public void onClick() {
                            mDeleteFileDialog.dismiss();
                        }
                    }, new NotifyDialog.OnPositiveClickListener() {
                        @Override
                        public void onClick() {
                            mDeleteFileDialog.dismiss();
                            if (PlaybackActivity.this.isChecked) {
                                deleteAllFiles();
                            } else {
                                FileInfo fileInfo = mAdapter.getItem(mCoverFlowCarousel.getSelectedPos());
                                deleteFile(fileInfo);
                            }
                        }
                    });
            mDeleteFileDialog.setOnCheckedChangeListener(onCheckedChangeListener);
        }

        if (!mDeleteFileDialog.isShowing()) {
            mDeleteFileDialog.show(getSupportFragmentManager(), "Delete_File_Dialog");
        }
    }

    private final NotifyDialog.OnCheckedChangeListener onCheckedChangeListener = new NotifyDialog.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(boolean isChecked) {
            PlaybackActivity.this.isChecked = isChecked;
        }
    };

    private void showProgressDialog(FileInfo fileInfo) {
        if (fileInfo == null) return;
        //Intercept video based on two point of time from selected video file and download it
/*        FileInfo info = VideoManager.getDownloadFileInfo(fileInfo.getStartTime().getTimeInMillis(),
                fileInfo.getEndTime().getTimeInMillis());
        if (info == null) {
            Dbug.e(tag, "info is null");
            MainApplication.getApplication().showToastShort("Can not download");
            return;
        }*/
        DownloadDialog downloadDialog = DownloadDialog.newInstance(fileInfo);
        downloadDialog.show(getSupportFragmentManager(), "DownloadDialog");
    }

    private void showStopRecordingDialog(final OnClickStateListener listener) {
        mStopLocalRecordingDialog = NotifyDialog.newInstance(R.string.dialog_tips, R.string.recording_will_stop,
                R.string.dialog_no, R.string.dialog_yes, new NotifyDialog.OnNegativeClickListener() {
                    @Override
                    public void onClick() {
                        mStopLocalRecordingDialog.dismiss();
                        mStopLocalRecordingDialog = null;
                        if (listener != null) {
                            listener.onCancel();
                        }
                    }
                }, new NotifyDialog.OnPositiveClickListener() {
                    @Override
                    public void onClick() {
                        mStopLocalRecordingDialog.dismiss();
                        mStopLocalRecordingDialog = null;
                        if (listener != null) {
                            listener.onConfirm();
                        }
                    }
                });
        mStopLocalRecordingDialog.setCancelable(false);

        if(!mStopLocalRecordingDialog.isShowing()){
            mStopLocalRecordingDialog.show(getSupportFragmentManager(), "Stop_local_recording");
        }
    }

    private void tryToStopRecording(int position) {
        final FileInfo info = mAdapter.getItem(position);
        showStopRecordingDialog(new OnClickStateListener() {
            @Override
            public void onCancel() {
                handleAutoPlay();
            }

            @Override
            public void onConfirm() {
                if (info != null) {
                    ClientManager.getClient().tryToRecordVideo(false, new SendResponse() {
                        @Override
                        public void onResponse(Integer code) {
                            if (code != SEND_SUCCESS) {
                                Dbug.e(tag, "Send failed");
                            } else {
                                ToastUtil.showToastShort(info.getName());
                                showPlaybackDialog(info.getPath(), info.getStartTime().getTimeInMillis());
                            }
                        }
                    });
                } else Dbug.e(tag, "Select fileInfo is null");
            }
        });
    }

    private void startDebug(){
        fps = 0;
        isStartDebug = true;
        if(mHandler != null){
            mHandler.sendEmptyMessage(MSG_FPS_COUNT);
        }
        if(mDebugHelper == null){
            mDebugHelper = new DebugHelper();
            mDebugHelper.registerDebugListener(mIDebugListener);
        }
        mDebugHelper.startDebug();
    }

    private void closeDebug(){
        if(mDebugHelper != null){
            isStartDebug = false;
            fps = 0;
            if(mHandler != null){
                mHandler.removeMessages(MSG_FPS_COUNT);
            }
            mDebugHelper.unregisterDebugListener(mIDebugListener);
            mDebugHelper.closeDebug();
            mDebugHelper = null;
        }
    }

    private void updateDebug(int dropCount, int dropSum){
        if(mStreamView != null){
            InfoHudViewHolder mHudViewHolder = mStreamView.getHudView();
            if(mHudViewHolder != null){
                mHudViewHolder.setRowValue(R.string.drop_packet_count, dropCount+"");
                mHudViewHolder.setRowValue(R.string.drop_packet_sum, dropSum+"");
            }
        }
    }

    private void updateDebugFps(int fps){
        if(mStreamView != null){
            InfoHudViewHolder mHudViewHolder = mStreamView.getHudView();
            if(mHudViewHolder != null){
                mHudViewHolder.setRowValue(R.string.fps, fps+"");
            }
        }
    }

    private IDebugListener mIDebugListener = new IDebugListener() {
        @Override
        public void onStartDebug(String remoteIp, int sendDataLen, int sendDataInterval) {

        }

        @Override
        public void onDebugResult(int dropCount, int dropSum) {
            updateDebug(dropCount,dropSum);
        }

        @Override
        public void onError(int code, String message) {
            Dlog.w(tag, message);
        }
    };
}
